行の部分文字列

行の部分文字列

ログファイルがたくさんあります。

workstation_2020_10_30-230600.log
workstation_2020_11_01-143352.log
workstation_2020_11_02-123203.log
workstation_2020_11_02-181803.log
workstation_2020_11_02-194433.log
workstation_2020_11_02-203701.log

こんなライン

I 06Nov20 13:48:11.838: PrintConsole    PrintConsole(1) unknown 0   2386    ExposureStatusChanged: ExposureId=2386,ExposureName=foobar.tif,ExposureStatus=Successful,PercentComplete=100,GroupingCount=30,OrderingTimeout=0,IsComplete=True

IsComplete=Trueタイムスタンプと公開ファイル名を抽出するために、部分文字列が見つかったすべての行を確認したいと思います(後述ExposureName=)。

上記の例では、出力は次のようになります。

06Nov20 13:48:11 foobar.tif

私の最高の結果は

cat workstation/* | grep tif.*IsComplete=True | cut -d '=' -f 3 | cut -d ',' -f 1 | sort


foobar.tif
foobar2.tif
foobar3.tif
...

これは私にタイムスタンプを与えません。ループや関数を書かずに簡単にできる方法がわかりません...

ベストアンサー1

awkGNUを3番目の引数として使用すると仮定すると、次のmatch()プログラムが浮上します。

awk '/IsComplete=True/{match($0,"ExposureName=([^,]+)",a); print $2,$3,a[1]}' *.log

これは文字列を含むすべての行と一致し、IsComplete=True「パターンを抽出してからExposureName=」では,ない文字を抽出し、後者の部分(ファイル名など)を配列変数に格納するキャプチャグループに入れますa

次に、日付と時刻を含む2番目と3番目の「単語」(スペースで区切られたフィールド)を印刷し、呼び出しからキャプチャグループの内容を印刷しますmatch()

あなたの例

06Nov20 13:48:11.838: foobar.tif

タイムスタンプのms部分を削除するには、次のようにgensub()このフィールドを変更できます。

awk '/IsComplete=True/{match($0,"ExposureName=([^,]+)",a); print $2,gensub(/\..*$/,"","1",$3),a[1]}' *.log

$2フィールド(、、)の番号付けは、$3スペースの有無によって大きく異なります。これはawk基本的に行がフィールドに分割される方法なので、タイムスタンプ形式が変更された場合(たとえば、)などの構文を調整する必要があり06 Nov 20ます。print氏名。

おすすめ記事