パターンに対してファイル内のすべてのレコード(レコードは空白行として定義されています)を検索したいと思いますNAME#AAAA
。一致するものがあれば、#
レコードの前に1つを挿入し、age
レコードの最後に行を挿入します。age NIL
入力ファイル:
NAME#AAAA
STD 1
SEC A
AGE 5
NAME#BBBB
STD 2
SEC B
AGE 6
NAME#CCCC
STD 3
SEC C
AGE 7
NAME#AAAA
STD 4
AGE 9
NAME#AAAA
STD 7
SEC A
AGE 12
期待される出力
NAME#AAAA
STD 1
SEC A
#AGE 5
AGE NIL
NAME#BBBB
STD 2
SEC B
AGE 6
NAME#CCCC
STD 3
SEC C
AGE 7
NAME#AAAA
STD 4
#AGE 9
AGE NIL
NAME#AAAA
STD 7
SEC A
#AGE 12
AGE NIL
答え1
Perlの「段落モード」は、空の行(「段落」)で区切られたレコードを見るたびに、しばしば良い解決策です。
$ perl -00lpe 'if(/NAME#AAAA/){s/\bAGE\s/#$&/; s/$/\nAGE NIL/;}' file
NAME#AAAA
STD 1
SEC A
#AGE 5
AGE NIL
NAME#BBBB
STD 2
SEC B
AGE 6
NAME#CCCC
STD 3
SEC C
AGE 7
NAME#AAAA
STD 4
#AGE 9
AGE NIL
NAME#AAAA
STD 7
SEC A
#AGE 12
AGE NIL
説明する
-00
:これはPerlの短絡モードを有効にします。ここでは、各「段落」(空白ではなく行から空行までの集合)が「行」として扱われます。-l
:各入力レコード(各段落)から末尾の改行を削除し、print
各呼び出しに改行を追加します。-pe
:与えられたスクリプトを適用した後、各入力レコードを印刷します-e
。
したがって、これらのフラグはperl
入力ファイルを読み込み、各レコードにスクリプトを適用し、結果を印刷します。スクリプト自体が行うことは次のとおりです。
if(/NAME#AAAA/)
:このレコードが一致した場合NAME#AAAA
。s/\bAGE\s/#$&/
: はs/foo/bar/
代替演算子です。foo
に置き換えられますbar
。ここではAGE
前に付いた自体に置き換えます#
。単語の境界と一致し、一致などの項目は\b
除外されます。 「何でも一致」を意味する特殊変数です。したがって、に置き換えられます。ADAGE
$&
s/\bAGE\s/#$&/
AGE
#AGE
s/$/\nAGE NIL/
:$
レコードの終わりと一致します。したがって、それを別のものに置き換えると、レコードの末尾に追加されます。このコマンドはAGE NIL
一致するレコードの末尾に追加されます。
ここのすべての操作は大文字と小文字を区別します。大文字と小文字を区別しない一致が必要な場合は、次のコマンドを使用します。
perl -00lpe 'if(/NAME#AAAA/i){s/\bAGE\s/#$&/i; s/$/\nAGE NIL/i;}' file