単一パスでファイルから複数の値を抽出するには?

単一パスでファイルから複数の値を抽出するには?

私は巨大なシミュレーションログファイル(約6GB)を持っています。このファイルには、数百万行のうち特定の時間に頻繁に繰り返される2行があります。

...
Max value of omega = 3.0355
Time = 0.000001
....
Max value of omega = 4.3644
Time = 0.000013
...
Max value of omega = 3.7319
Time = 0.000025
...
...
...
Max value of omega = 7.0695
Time = 1.32125
...
... etc.

「オメガの最大値」と「時間」を抽出し、単一ファイルの列として保存したいと思います。

#time max_omega
0.000001 3.0355
0.000013 4.3644
0.000025 3.7319
...etc.

私は次のように進みます:

# The following takes about 15 seconds
grep -F 'Max value of omega' logfile | cut -d "=" -f 2 > max_omega_file.txt  

、「時間」も同様です

# This also takes about 15 seconds
# Very important: match exactly 'Time =' because there other lines that contain the word 'Time'
grep -F 'Time =' logfile | cut -d "=" -f 2 > time.txt

その後、このコマンドを使用して2つの列ファイルを生成する必要がありますpaste。最初の列はTime.txtで、2番目の列は「max_omega_file.txt」です。

ご覧のとおり、上記の手順は2倍の時間がかかります。一度に同じ結果を達成して時間を節約するソリューションがあるかどうか疑問に思います。

答え1

sed -n '/^Max/ { s/^.*=\s*//;h; };
        /^Time/{ s/^.*=\s*//;G; s/\n/ /;p; }' infile
  • 一致実行構文/.../{ ... }
    ここに含まれるコマンドは、{...}正規表現/パターンと一致する行でのみ実行されます/.../

  • s/^.*=\s*//:末尾と空白(存在する場合)
    の両方を削除します。=\s*

  • h
    結果を予約済みスペースにコピーします。

  • G
    改行文字を含むパターンスペースに予約済みスペースを追加します。

  • s/\n/ /
    埋め込み改行文字をパターンスペースのスペースで置き換えます。

  • p
    パターンスペースを印刷します。Pここでコマンドを使用することもできます。

    0.000001 3.0355
    0.000013 4.3644
    0.000025 3.7319
    1.32125 7.0695
    

同様の方法を提案@stevesliwaこれはs//<replace>/、最後のゲームで交換を実行することを簡単に表現したものです。

sed -n '/^Max.*=\s*/ { s///;h; };
        /^Time.*=\s*/{ s///;G; s/\n/ /;p; }' infile

答え2

より速くなると約束することはできませんが、awkで次のことを行うことができます。

awk -F' = ' '$1=="Max value of omega" {omega = $2} $1=="Time" {print omega,$2}' file

答え3

$ awk 'BEGIN{print "#time", "omega"} /^Max value of omega =/{omega=$NF; next} /^Time =/{print $NF, omega}' file
#time omega
0.000001 3.0355
0.000013 4.3644
0.000025 3.7319
1.32125 7.0695

しかし、これはより速いかもしれません。

$ grep -E '^(Max value of omega|Time) =' file |
    awk 'BEGIN{print "#time", "omega"} NR%2{omega=$NF; next} {print $NF, omega}'
#time omega
0.000001 3.0355
0.000013 4.3644
0.000025 3.7319
1.32125 7.0695

答え4

grep複数のパターンを一度に検索できます

-e PATTERNS, --regexp=PATTERNS
PATTERNS をパターンとして使用します。 このオプションを複数回使用する場合または -f(--file) オプションと組み合わせます。指定されたすべてのパターンを検索。このオプションは、「-」で始まるパターンを保護するために使用できます。

だから

grep -F -e 'Max value of omega = ' -e 'Time = ' logfile

これにより、検索スペースのサイズが縮小され、他の提案の1つにプロセスを公開できます。

関連情報