プレーンテキストファイルの複雑なパターンから数値データを抽出し、表形式の出力を生成します。

プレーンテキストファイルの複雑なパターンから数値データを抽出し、表形式の出力を生成します。

SOSの問題です。教授は、元博士後の研究者(私にそれがどのように機能するかを説明してくれた)が私たちに譲り受けた長期実行シミュレーションコードの出力を取得するように依頼しました。

私はいくつかの小さなテストを実行しましたが、すべてがうまくいきました。その後、約1ヶ月前にシミュレーション全体を開始し、その後継続的に実行してきました。しかし、ほんの数分前に、いくつかのメモリの問題のために、フォーマットされたテーブル出力をディスクに書き込む前にプログラムがクラッシュしました。

幸い、中間結果のターミナルエコーを有効にし、ロールバック履歴を大きな値に設定しました。ロールバックモードに切り替えて、完全な端末ダンプをテキストファイルにコピーし、バックアップコピーを作成して出力の一部を回復しました。

今、このターミナル出力は非常に冗長です(デバッグ目的で意図的にそれを行います)。以下は、回復された端末出力テキストファイルのスナップショットです(と呼びますterminal_output.txt)。

1 Linear search iteration no. 1 begins: Attempting to blah blah with 1 ...
2 blah blah 
3 blah 
4 blah blah blah
5 lorem ipsum 
.........
........
75 Success with 128 blah ....
76 blah blah
77 blah blah
78 result_flag: 1, exit_reason: 6
79 blah
80 Completed optimal computation with T_init = 25.00 degC & T_sink = 35.00 degC

これにより、この正確なパターンが繰り返されます。例えば、

81 Linear search iteration no. 2 begins: Attempting to blah blah with 1 ...
82 blah
......
95 Success with 307 blah ....
......
......
100 Completed optimal computation with T_init = 30.00 degC & T_sink = 40.00 degC

私の要件は、次の情報を抽出して次の表形式の出力を生成することです。

25  35  128
30  40  307
...........
...........

T_initつまり、最初の列と2番目の列は、それぞれに対応する値から、T_sinkで始まる行から来ますCompleted。 3番目の列は最初からの行値です​​(役に立つ場合はSuccess常に5行進む)。Completed列の間には、スペース、タブ、カンマなど、すべての区切り文字が許可されます。

grepsedなどの標準 *nix ユーティリティを使用してawkローカルでこれを実行したいと思いますvi/vim。パイプラインでリンクされた単一行またはリンクされたbashスクリプトが機能します。必要に応じて、他のスクリプト言語pythonも使用する意図があります。perl

答え1

本質的に、所望の部分を捕捉し、不要な部分を廃棄する問題である。たとえば、sed整数値をキャプチャして(を使用してSuccess予約済みスペースにコピーできます)。時間)、検索して追加します(G)を次の行にキャプチャされた番号に変換しますCompleted

sed -nE \
  -e '/Success/ {s/.* ([0-9]+).*/\1/; h;}' \
  -e '/Completed/{G; s/.*T_init = ([0-9]+)\.00 degC & T_sink = ([0-9]+).*\n/\1 \2 /; p;}
' terminal_output.txt

PerlはIMHOがより読みやすい表現に富んだ構文を提供します。

perl -lne '
  our $a = $1 if /Success.*?(\d+)/; print join " ", /(\d+)\.\d+/g, $a if /Completed/
' terminal_output.txt

希望の出力を生成

25 35 128
30 40 307

答え2

POSIX互換sed:

grep -e 'Success' -e 'Completed' your_file | sed 'N;s/Success with \([[:digit:]]\+\).*T_init = \([^[:space:]]\+\).*T_sink = \([^[:space:]]\+\).*/\2 \3 \1/;s/\.00//g'

GNU sed:(少なくともCentOSの4.2.2では一致しません.\n

grep -e 'Success' -e 'Completed' your_file | sed 'N;s/Success with \([[:digit:]]\+\).*\n.*T_init = \([^[:space:]]\+\).*T_sink = \([^[:space:]]\+\).*/\2 \3 \1/;s/\.00//g'

Successとを含む行をつかみ、2つのCompleted行(必要以上に明示的)を処理して、関心のある3つのフィールドを取り出し、1つの行に並べ替えます。

これにより、重要な小数部(まだ単一の末尾ゼロを含む.00ものなど)を保持しながら、すべての数字が切り捨てられます。12.20

...Completed警告この行の一部にまたはが含まれていると機能しません。Success

答え3

クイックawkコマンドを使用すると起動できます。

awk '$2 ~ /Success/{a=$4;next}; $2 ~ /Completed/{b=$8;c=$13;print a,b,c}' terminal_output.txt

Success行の前に複数の行がある場合はCompleted機能しません。

関連情報