大きなファイル(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
:\3
n番目のグループのアクセスモード()
出力:
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
最初の行では、次のN
2行を読み取ります(したがって、パターンスペースには3行があります)。
次に、すべての入力ライン(最初の行を含む)に対して追加のN
ラインを取得します(したがって、パターンスペースには4本のラインがあります)。パターンスペースの3行目が一致すると、Fail
パターンスペースの各行の前に行を追加します#
。その後、何があってもP
最初の\n
ewlineに印刷し、D
最初の\n
ewlineに移動してサイクルを再開します。
答え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
Fail
3行目で4つの連続行を見つけます。見つかると、#
各改行文字の後に配置されます。もっと詳しく見ると、置換コマンドは正規表現の
s/old/new
whereに似ています。old
私たちの場合です\n([^\n]*)\n([^\n]*)\n([^\n]*Fail[^\n]*)\n
。これを4つの部分に分けてみましょう。\n([^\n]*)
最初の行を見つけてグループ1に保存します。\n([^\n]*)
2行目を見つけてグループ2に保存します。\n([^\n]*Fail[^\n]*)
3行目を探します。ただし、その行に単語が含まれている場合にのみ一致しますFail
。\n
4番目の改行文字と一致します。 (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'