完了していない履歴アクティビティのログファイルを取得しようとしています。たとえば、「ID 1234で活動を開始しています...」を記録して成功すると、次の行は「活動1234完了」になります。
その「完了」行が後に出ない「開始...」行を取得しようとしています。
ログファイルの例
Starting activity for ID 1234
ID 1234 completed successfully
Starting activity for ID 3423
ID 3423 completed successfully
Starting activity for ID 9876
ID 9876 completed successfully
Starting activity for ID 99889
ID 99889 completed successfully
Starting activity for ID 10011
ID 10011 completed successfully
Starting activity for ID 33367
Starting activity for ID 936819
ID 936819 completed successfully
この例では、次のような出力が必要です。
Starting activity for ID 33367
…その後に「完了」の行がないからです。
私はこれを使って多くの成功をgrep
収めませんでした。awk
これらのツールのいずれかを使用することは可能だと思いますが、私のgrep
能力はawk
まだ進歩していません。
私に必要な結果を提供するための迅速で信頼性の高いgrep
モードを探しています。awk
答え1
代替方法は次のとおりですawk
。
awk '
/^Starting/ { I[$5] = $0 }
/^ID/ { delete I[$2] }
END { for (key in I) print I[key] }
' infile
出力:
Starting activity for ID 33367
連想配列は、I
示されたIDを追跡する。
答え2
sed '$!N;/\n.*completed/d;P;D' <input
これにより、文字列に一致する行が後に来ないすべての入力行が出力から削除されます。十分。
答え3
GNU sedを使用してこれを行う方法は次のとおりです。
sed -r 'N; /([0-9]+)\n\w+\s+\1/d; P; D' infile
N
パターン空間からさらに1行読みます。- 一致する正規表現は同じIDがあることを確認し、そうであればパターンスペース(
d
)を削除してループを再開します。 - 一致するものがない場合は、パターンスペースの最初の行を印刷して(
P
)削除します(D
)。
答え4
インストールがpcregrepをサポートしている場合は、複数行(-M)オプションが便利です。
pcregrep -M -o '\AStarting activity for ID (\d+)\n(?!ID \1)' t.z
ID 33367で活動を開始