検索、挿入、移動、挿入

検索、挿入、移動、挿入

パターンに対してファイル内のすべてのレコード(レコードは空白行として定義されています)を検索したいと思います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:exexvi

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\\nex各コマンドの後に改行を追加して、複数のコマンドを入力する簡単な方法を提供します。

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を展開します。

関連情報