パターンに対してファイル内のすべてのレコード(レコードは空白行として定義されています)を検索したいと思いますNAME#AAAA
。一致するものがあれば、#
レコード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
期待される出力
#AGE 5
NAME#AAAA
STD 1
SEC A
AGE NIL
NAME#BBBB
STD 2
SEC B
AGE 6
NAME#CCCC
STD 3
SEC C
AGE 7
#AGE 9
NAME#AAAA
STD 4
AGE NIL
#AGE 12
NAME#AAAA
STD 7
SEC A
AGE NIL
また、その逆も必要です。変更を元に戻すだけです。これらすべてがAIXシステムで実行されていることに注意してください。
答え1
ex
これは、POSIX 指定ファイル編集ツールの完全なユースケースです。
vi
(しかし、私が試したことがあるならば、コロンで始まるすべての入力がコマンドであるというex
事実に精通しているでしょう。これは全身です。)vi
:
ex
ex
vi
printf %s\\n 'g/NAME#AAAA/ /AGE/t- | s/^/#/ | /AGE/s/.*/AGE NIL/' x | ex input.txt
ファイルを実際に保存する前にテストするには、x
パイプシンボルの前の最後のシンボルをに変更すると、%p
変更されたファイルは保存されませんが、変更されたバージョンはとして印刷されますstdout
。したがって、テストコマンドは次のようになります。
printf %s\\n 'g/NAME#AAAA/ /AGE/t- | s/^/#/ | /AGE/s/.*/AGE NIL/' %p | ex input.txt
説明する:
printf %s\\n
ex
各コマンドの後に改行を追加して、複数のコマンドを入力する簡単な方法を提供します。
g/regex/
グローバルコマンドです。与えられた正規表現に一致する各行で、次のコマンドを実行します(次の改行文字まで)。
/AGE/t-
パターンに一致する次の行を/AGE/
現在の行の前の位置にコピーしますNAME#AAAA
。また、カーソルを行の新しいコピーに移動します(「現在の行」になります)。
|
のコマンド区切り記号ですex
。
s/^/#/
コピーした行AGE
の前にハッシュタグを追加してください。 (または方言に応じてポンド記号もあります。);)
次のコマンドは実際には2つの部分で構成されています。/AGE/
アドレスは、パターンを含む次の行でコマンドを実行し、その行のs/.*/AGE NIL/
内容をに置き換えますAGE NIL
。
x
ファイルへの変更を保存して終了します。
変更をキャンセル
変更を取り消すには、次の手順を実行します。
printf %s\\n 'g/NAME#AAAA/ ?^#AGE? m /^AGE/ | s/^#// | -d' %p | ex input.txt
その後、変更が確認されたら、実際に変更を保存します。
printf %s\\n 'g/NAME#AAAA/ ?^#AGE? m /^AGE/ | s/^#// | -d' x | ex input.txt
説明する:
前と同じグローバルコマンドです。
NAMEで始まる行を選択し、#AGE
で始まる次の行に戻りますAGE
。
先行を削除します#
。
直前の行-d
(NIL年齢行)を削除します。
変更を印刷または保存します。
答え2
perl -pe 'BEGIN{$/=""}
s/^(NAME#AAAA.*\n)(AGE.*?)(\n+)$/#$2\n$1AGE NIL$3/s' ex1
非常に簡単な説明:
For all the registers in input | perl -p
separator= one or more empty lines | BEGIN{$/=""}
do:
| substitute | s/
| ^(NAME AAAA.*\n)(AGE.*?)(\n+)$ | regex /
| 1 2 3 |
| by | /subst. string including
| # $2 \n $1 AGE NIL $3 | capture groups/
| |
| and print | ...from option -p
修正する:
NAME#AAAAの代わりに変数を使用できますか?
perl -pe '
BEGIN{
$/="";
$f=shift; }
s/^(NAME#$f.*\n)(AGE.*?)(\n+)$/#$2\n$1AGE NIL$3/s' AAAA ex1
このバージョンでは模様パラメータ(例:「AAAA」):
- 行4:コマンドラインから最初の引数(「AAAA」)を取得して$ fに保存します。
- 行5:代替モードで$ fを展開します。