次の行に特定の一致が含まれていない場合にのみ、行を印刷します


12

完了しなかったログに記録されたアクティビティのログファイルを検索しようとしています。たとえば、「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

...後に「完成した」行が続かないためです。

私はこれをやってみたことgrepawk、しかし、多くの成功を持っていませんでした。これらのツールのいずれかを使用してそれを実行できると想定していますが、私grepawkチョップは高度ではありません。

迅速かつ信頼性の高い探しているgrepか、awk私はここに必要な結果を与えることがパターン。


grep + awkで簡単にできるとは思いませんが、なぜそうしているのか少し説明していただけますか?実行中のすべてのアクティビティの出力(成功または完了していないなど)
デイジー

@ warl0ck、私は「未完成」を探しています。
PattMauler

回答:


10

以下が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連想配列は、IDSが見てきた何を追跡します。


「Starting ...」と「Completed ...」のログ行が隣接/連続していない状況にも対応しているように見えるため、これは非常にうまく機能します。@Thorに感謝します!
PattMauler

どういたしまして。これはIDのみを保存し、ルックアップ時間はO(1)であるため、(ほぼ)任意のサイズの入力で効率的に動作するはずです。
トール

いいね 1つだけ:@RobertL(unix.stackexchange.com/a/243550/135943)から学んだように、配列要素を作成するために値を割り当てる必要はありません。そのため、代わりにをI[$5] = 1使用できますI[$5]。(値については気にせず、要素を存在させたいだけで、単に名前を付けてそれを実現します。)
ワイルドカード

@Wildcard:あなたは正しいですが、OPの質問と彼が求めている出力のようなgrepを確認した後、行全体を覚えて最後に出力する方が適切です。
トール

3
sed '$!N;/\n.*completed/d;P;D' <input

これにより、出力から、完了した文字列に一致する行が後に続かないすべての入力行が削除されます。


2

GNU sedでこれを行う方法は次のとおりです。

sed -r 'N; /([0-9]+)\n\w+\s+\1/d; P; D' infile
  • N もう1行をパターンスペースに読み込みます。
  • 一致正規表現は、同一のIDが見つかったかどうかを確認します。見つかった場合、パターンスペースが削除され(d)、サイクルが再開されます。
  • 一致しなかった場合は、パターンスペースの最初の行(P)を印刷して削除します(D)。

ここには何も拡張されて-rいないので、必要ありませんよね?
ルイマドックス14年

1
@lmmx:キャプチャグループをエスケープする必要があるため必要です。これは数量詞にも当てはまります+
トール14年

ああOK!私はそれを修正し、それは必要ではないと言われました、明確にするためのおかげで
ルイ・マドックス14年

1

インストールがpcregrepをサポートしている場合、複数行(-M)オプションが便利です。

pcregrep -M -o '\AStarting activity for ID (\d+)\n(?!ID \1)' t.z

ID 33367の開始アクティビティ

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.