Bashスクリプト端末でのテキストの検索と置換

Bashスクリプト端末でのテキストの検索と置換

/home/count/1/details/info.txt次のファイルがあります

title1 {
key1 value1
key2 value2
key3 value3
}

info {
name1 text
post1 anything
salary 1
work day1
work day2
work day3
}

work {
department sell
store ground
remarks
}

contact {
required No
}

今私には必要です。変化上から:

title1 {
key1 value1
key2 value2
key3 value3
}

info {
name1 text
post1 anything
salary 1
work day1
work day2
work day3
work day4
work day5
work day8
}

work {
department sell
store ground
remarks
Absent No
}

contact {
required No
}

work day4、、、work day5情報グループに3つの新しい値が追加されましたwork day8。ワークグループは新しい値、つまりを取得しますAbsent

タイトル(例:title1、情報、作品)は固定されており、変更することはできません。ただし、{}の間の値は動的に可変であり、任意の値にすることができます。ただし、コア操作は固定されており、追加または削除のみ可能で、変更は不可能です。

これを行うには、bashファイルを作成する必要がありました。最小バージョンのubuntu 20.04サーバーでのみ端末を使用できます。

アイデア、提案、助けがありますか?

ありがとう

答え1

そしてperl

perl -0777 -pi -e '
  s{^info\s*\{.*?\K(?=\})}{join "", map {"work day$_\n"} 4,5,8}mse;
  s{^work\s*\{.*?\K(?=\})}{Absent No\n}ms' /home/count/1/details/info.txt

答え2

awk 'BEGIN {RS=ORS="\n\n"};
     /^info {/ { gsub("}","work day4\nwork day5\nwork day8\n}") };
     /^work {/ { gsub("}","Absent No\n}") };
     1' info.txt 

これは、awkに入力ファイルを一度に1つの段落で読み取るように指示します(つまり、入力レコード区切り文字を1つではRSなく2つの改行区切りレコードに設定することによって\n\n)。また、出力レコード区切り文字を に等しく設定して、RS出力レコード間に空白行があるようにします。

次に、この関数を使用して、一致する各段落(「info {」または「work {」で始まる段落)の最後gsub()に追加の行を追加します。}実際には変えるこのレコードの末尾には}追加の行があります。そしてa }- これは、追加の行を挿入するのと実質的に同じです。

最後は1awk の略printで、変更の有無にかかわらずすべてのレコードを印刷します。

答え3

また、awk短絡モードで次のコードを試すことができます。


awk -v s1="Absent No\n" -v s2="work day4\nwork day5\nwork day8\n"  -v OFS="\n" -v RS= -v ORS='\n\n' '$1 == "work" {sub(/}/, s1"&")} $1 == "info" {sub(/}/, s2"&")} 1' file
title1 {
key1 value1
key2 value2
key3 value3
}

info {
name1 text
post1 anything
salary 1
work day1
work day2
work day3
work day4
work day5
work day8
}

work {
department sell
store ground
remarks
Absent No
}

contact {
required No
}

答え4

sed -i -e '
  /^info {/,/}/ s/}/work day4\nwork day5\nwork day8\n&/

  /^work {/,/}/ s/}/Absent No\n&/
' /home/count/1/details/info.txt

perl -i -lpe '
  /^info \{/.../}/ and /}/ && do{
  print for map { "work day$_" } 4,5,8}; 

  /^work \{/.../}/ and /}/ &&
    print "Absent No";
' /home/count/1/details/info.txt

関連情報