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
列の間には、スペース、タブ、カンマなど、すべての区切り文字が許可されます。
grep
、sed
などの標準 *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
機能しません。