一致後のラインNの交換

一致後のラインNの交換

500行のテキストを含むファイルがあるとします。

one
two
three
four
five
six
seven
eight
nine
ten
.
.
.
five-hundred

一致後に5行目を特定の文字列に置き換えるには、次の手順を実行します。

sed '/two/{n;n;n;n;n;s/.*/MODIFIED/}' inputfile

出力:

one
two
three
four
five
six
MODIFIED
eight
nine
ten
.
.
.
five-hundred

しかし、試合が終わった後に60番のラインを交換したい場合はどうすればいいですか?私は「n」を60回書きたくありません。

x、h / H、g / G、および範囲を試してみましたが、まだ希望の出力を得ることはできません。

答え1

解決策awk

awk '/two/{ n=NR+5 } NR==n{ sub(/.*/, "MODIFIED") }1' file

または路線を変更したい場合

awk '/two/{ n=NR+5 } NR==n{ $0="MODIFIED" }1' file

答え2

これらの操作では、検索パターンがオフセットの前に再表示される場合は、どうすればよいかを検討する必要があります。

awk -v offset=60 '
    /two/ {x[NR + offset]}
  NR in x {delete x[NR]; $0 = "MODIFIED"}
          {print}'

上記の60行が含まれるたびに、ラインの交換が保証されますtwo

答え3

/two/{
    :loop
    N
    /\(\(.*\n\)\{5\}\).*/{
        s//\1Modified/
        b
    }
    b loop
}

保存x.sedして次のように実行します。

sed -f x.sed file

またはGNU Sedを使用する1行のコード:

sed '/two/{:a;N;/\(\(.*\n\)\{5\}\).*/{s//\1Modified/;b;};ba;}' file

ライン別分析:

  • 1-2:一致するものが見つかったら繰り返しを開始します。このサイクルでは
    • 3:コマンドを使用してパターンスペースに行を追加しますN
    • 4:5つの改行がある場合(デフォルトの正規表現は\(.*\n\)\{5\}-)、キャプチャグループに入れ、最後の行(.*)をキャプチャされていません。
      • 5: 全体のパターン空間*をキャプチャグループに置き換え、その後にModified行を追加します。
      • 6: サイクルを壊しなさい。
    • 8: 言い換えてくださいloop

*空の正規表現スロットは、以前に使用された正規表現と同じなので、5行目はと同じですs/\(\(.*\n\)\{5\}\).*/\1Modified/


あまり難解ではないのはAwkを使うことです。

awk '{c--};/two/{c=5};c==0{$0="Modified"};{print}' file

最初の値は減少するカウンターcで、すべての変数はc最初にゼロであるため、一致する項目が見つかった場合にのみ正の値になります。

より明示的なアプローチは次のとおりです。

awk 'BEGIN{c=-1};/two/{c=5};c==0{$0="Modified"};{print};c>=0{c=c-1}' file

便利なSedリソース:

答え4

すべてのUnixシステムのすべてのシェルでawkを使用して、これらの一致が5行の範囲内で繰り返し発生しないと仮定し、完全な行文字列一致を実行します。

$ awk 'c&&!--c{$0="MODIFIED"} $0=="two"{c=5} 1' file
one
two
three
four
five
six
MODIFIED
eight
nine
ten
.
.
.
five-hundred

バラよりhttps://stackoverflow.com/questions/17908555/printing-with-sed-or-awk-a-line-following-a-matching-pattern/17914105#17914105

関連情報