パターンを見つけて、前の2行、後の1行の先頭に#を挿入します。

パターンを見つけて、前の2行、後の1行の先頭に#を挿入します。

大きなファイル(2000行以上)があります。パターンを見つけたら、上の2行、下の1行の先頭に#を入れる必要があります。また、パターンが見つかった行の先頭に#を挿入してください。環境はRed Hat Linuxです。また、説明もしていただければいいと思います。

たとえば、次のテキストを参照して「Fail」を検索し、その文字列の前の2行目とその後の1行目(行の先頭)を検索します。また、#行には「Fail」という文字列が含まれています。

Name
Number
Reason = Pass
Reasult
Name
Number
Reason = Pass
Reasult
Name
Number
Reason = Fail
Reasult
Name
Number
Reason = Pass
Reasult
Name
Number
Reason = Fail
Reasult
Name
Number
Reason = Pass
Reasult

答え1

以下を使用することをお勧めしますperl

perl -p0e 's/(.*\n)(.*\n)(.*Fail\n)/#\1#\2#\3#/g' file

仕組みは次のとおりです。

  • -p:すべての入力ラインにわたって印刷プログラムを繰り返します。
  • -0: レコード区切り文字として null を仮定します。
  • -e:コマンドラインからプログラムを実行する
  • s/x/y/g: ファイルのどこでも x を y に置き換えます。
  • (): 正規表現を一緒に結合
  • .*:改行文字を除くすべての文字が0回以上繰り返されます。
  • \n: 新しいチーム
  • \1、、\2\3n番目のグループのアクセスモード()

出力:

Name
Number
Reason = Pass
Reasult
Name
Number
Reason = Pass
Reasult
#Name
#Number
#Reason = Fail
#Reasult
Name
Number
Reason = Pass
Reasult
#Name
#Number
#Reason = Fail
#Reasult
Name
Number
Reason = Pass
Reasult

答え2

以下は、sedスライドウィンドウを使用するソリューションです(したがって、一度にパターンスペースに4本以上の線が表示されません)。

sed '1{N;N;};$!N;/.*\n.*\n.*Fail.*\n.*/{s/^/#/;s/\n/&#/g;};P;D' infile

最初の行では、次のN2行を読み取ります(したがって、パターンスペースには3行があります)。
次に、すべての入力ライン(最初の行を含む)に対して追加のNラインを取得します(したがって、パターンスペースには4本のラインがあります)。パターンスペースの3行目が一致すると、Failパターンスペースの各行の前に行を追加します#。その後、何があってもP最初の\newlineに印刷し、D最初の\newlineに移動してサイクルを再開します。

答え3

$ sed -r 'H;1h;$!d;x; s/\n([^\n]*)\n([^\n]*)\n([^\n]*Fail[^\n]*)\n/\n#\1\n#\2\n#\3\n#/g' file
Name
Number
Reason = Pass
Reasult
Name
Number
Reason = Pass
Reasult
#Name
#Number
#Reason = Fail
#Reasult
Name
Number
Reason = Pass
Reasult
#Name
#Number
#Reason = Fail
#Reasult
Name
Number
Reason = Pass
Reasult

どのように動作しますか?

  • H;1h;$!d;x

    このコマンドはファイル全体を読み込みます。

  • s/\n([^\n]*)\n([^\n]*)\n([^\n]*Fail[^\n]*)\n/\n#\1\n#\2\n#\3\n#/g

    Fail3行目で4つの連続行を見つけます。見つかると、#各改行文字の後に配置されます。

    もっと詳しく見ると、置換コマンドは正規表現のs/old/newwhereに似ています。old私たちの場合です\n([^\n]*)\n([^\n]*)\n([^\n]*Fail[^\n]*)\n。これを4つの部分に分けてみましょう。

    1. \n([^\n]*)最初の行を見つけてグループ1に保存します。

    2. \n([^\n]*)2行目を見つけてグループ2に保存します。

    3. \n([^\n]*Fail[^\n]*)3行目を探します。ただし、その行に単語が含まれている場合にのみ一致しますFail

    4. \n4番目の改行文字と一致します。 (4行目のテキストは保存されません。必要ありません。)

    上記と一致する行が4つある場合は、各行の後に追加された改行文字を\n#\1\n#\2\n#\3\n#除いて入力と同じ内容に置き換えます。#\n

    マックエスエックス(BSD)

上記はGNU sedでテストされました。 BSD sedを使用している場合は、以下を試してください。

sed -E 'H;1h;$!d;x; s/\n([^\n]*)\n([^\n]*)\n([^\n]*Fail[^\n]*)\n/\n#\1\n#\2\n#\3\n#/g' file

答え4

より簡単なバリエーション@don_crisstiスクリプト

sed ':a;/\(.*\n\)\{2\}/{P;D};N;/= Fail$/! ba;N;s/^/# /gm'

関連情報