まだ複雑なログファイルのために問題が発生しています。私が望むのは、最初に文字列Xに一致する行を検索し、次に文字列Yに一致する行を見つけることです。それでは一緒に印刷したいです。問題は時々XはあるがYはないということです。
入力例
31 X
32 Y
33 X
34 Y
35 X
36 X
37 Y
38 X
39 X
期待される出力
31 X
32 Y
33 X
34 Y
36 X
37 Y
したがって、行35、38、39は文字列Yがないため省略されます。
私の出発点は次のとおりです。
cat $filename | grep -E X\|Y | grep -A1 'X'
ただし、これは行35、38、39をフィルタリングしません。私が望むのは条件です。 Yがある場合は、X行のみを印刷してからY行を印刷します。それ以外の場合は何も印刷されません。
答え1
使用sed
:
sed -n ':b /X/ { h; n; /Y/! b b; H; x; p; }'
出力:
31 X
32 Y
33 X
34 Y
36 X
37 Y
答え2
その他sed
:
$ sed -e '/X/{
$!N
/\n.*Y/!D
}' file
31 X
32 Y
33 X
34 Y
36 X
37 Y
答え3
これを行うにはいくつかのツールがあります。持っている場合pcregrep
(配布デポにある必要があります)、次のことができます。
$ pcregrep -M 'X\n[^\n]+Y' file
31 X
32 Y
33 X
34 Y
36 X
37 Y
この-M
スイッチを使用すると、パターンを改行文字、正規表現の一致、X
その後の改行文字、改行以外の文字、およびと一致させることができますY
。
別のオプションは、前の行が一致する場合は保存し、一致した場合はX
現在の行と一緒に印刷する小さなスクリプトを作成することですY
。たとえば、次のようになりますawk
。
$ awk '{if(last~/X/ && /Y/){print last"\n"$0}last=$0}' file
31 X
32 Y
33 X
34 Y
36 X
37 Y
またはパール:
$ perl -ne '$last=~/X/ && /Y/ && print "$last$_"; $last=$_' file
31 X
32 Y
33 X
34 Y
36 X
37 Y
答え4
質問にタグが付けられているのでawk
:
$ awk 'p2 == "X" && $2 == "Y" { print p; print } { p = $0; p2 = $2 }' file
31 X
32 Y
33 X
34 Y
36 X
37 Y
これにより、1行X
とその直後の行Y
(存在する場合)が印刷されます(または両方が印刷されません)。
変数p
とp2
は、変更されていない前の行と2番目の列をそれぞれ保持します。