パターンに一致するログファイルで数字を見つける方法

パターンに一致するログファイルで数字を見つける方法

以下を含むログファイルからいくつかの情報を抽出したいと思います。

...
Running ep. 0
...
...
Initial position for this ep is 7.338690864048985,28.51815509409351,11.795143979909135
...
...
...
Running ep. 1
...
...
Initial position for this ep is 10.599326804010953,7.514871863851674,14.843070346933654
...
...

これで、いくつかのデータを抽出できるbashコードができました。

cat screen2.dat|grep -oP 'Running ep. \K([0-9]+)|(?<=for this ep is )[+-]?[0-9]+([.][0-9]+)?'|paste -d' ' - -

ただし、出力は「Running ep」以降の数字にすぎません。 「このepの初期位置は」の後の最初の数字です。

0 7.338690864048985 
1 10.599326804010953 
.
.
.

次のようなことを期待していた

0 7.338690864048985 28.51815509409351 11.795143979909135
1 10.599326804010953 7.514871863851674 14.843070346933654
.
.
.

答え1

表現をあまりに過度に指定しているようですね。 substringの後には単一のfloatのみが一致しますfor this ep is。残りの行が必要な場合は、次のようなものを使用してください

grep -oP 'Running ep\. \K(.*)|for this ep is \K(.*)' screen2.dat |
paste -d ' ' - -

標準を使用してsed以下を作成できます。

sed -n -e 's/^Running ep\. //p' -e 's/.*for this ep is //p' screen2.dat |
paste -d ' ' - -

線の不要な部分を切り取ります(削除する項目がないものと交換)。

awk同じ方法で使用しても良いし、

awk '/^Running ep\. / || /for this ep is / { print $NF }' screen2.dat |
paste -d ' ' - -

または一度にすべてをフォーマットし、

awk '/^Running ep\. / { ep = $NF } /for this ep is / { print ep, $NF }' screen2.dat

答え2

あなたのコードは、ドット[+-]?[0-9]+([.][0-9]+)?の後にオプションの数字がある単一の数字と一致します。 3つが欲しいなら、こう言ってください。([+-]?[0-9]+([.][0-9]+)?,?){3}

しかし、あなたが本当にしたいのはsedただのスクリプトです。

sed -e '/Running ep. /{s///;h;}' -e '/.*for this ep is /!d;s///;H;x;s/[\n,]/ /g' screen2.dat
  • /Running ep. /{...}{}一致する行内でのみすべてを実行することです。Running ep.
  • これらの行の場合、以前にs///一致した部分を削除し、行をh前のスペースに移動します。
  • /.*for this ep is /!dいいえ!他のパターンと一致しない()を持つすべての行をd選択できます。
  • 残りはs///パターンを再び削除し、行の残りの部分はすべて数字のままにします。
  • Hep番号を取得できる予約済みスペースにこの残りを追加します。
  • xバッファを交換して、予約された空間から収集された2つの部分がパターン空間にあります。
  • s/[\n,]/ /g埋め込み改行とすべてのカンマを空白に置き換える

答え3

と究極pcregrepMモード:

$ <input pcregrep -M -o{1..4} --om-separator=' ' \
  '(?sm)^Running ep\. (\d+)$.*?^Initial position for this ep is ([+-]?\d+(?:\.\d+)?),((?2)),((?2))$'
0 7.338690864048985 28.51815509409351 11.795143979909135
1 10.599326804010953 7.514871863851674 14.843070346933654

ただし、Initial...特定の項目が欠落している場合は他の項目と一致し、指定されたRunning ep...値セットの前に誤ったep番号が表示されることがあります。.*?Running ep...

おそらくgawk次のようにする方が良いでしょう。

<input gawk -v 'FPAT=[+-]?[0-9]+([.][0-9]+)?' '
  /^Running ep/ && NF == 1 {ep = $1; next}
  /^Initial position for this ep is/ && ep != "" && NF == 3 {
    print ep, $1, $2, $3
    ep = "" # omit if there can be more than one "Initial position"
            # per ep.
  }'

ここで、FPATフィールドは正規表現(数値)に一致する文字列として定義され、出力された行だけを印刷します。初期位置さて、該当するものがあればランニングEPその行は以前見たことがあります。

答え4

すべてのUnixシステムのすべてのシェルでawkを使用してください。

$ awk '/Running ep/{ep=$NF} /Initial position/{print ep, $NF}' file
0 7.338690864048985,28.51815509409351,11.795143979909135
1 10.599326804010953,7.514871863851674,14.843070346933654

そのコンマを空白に置き換えるには、次の手順を実行します。

$ awk '/Running ep/{ep=$NF} /Initial position/{gsub(/,/," ",$NF); print ep, $NF}' file
0 7.338690864048985 28.51815509409351 11.795143979909135
1 10.599326804010953 7.514871863851674 14.843070346933654

関連情報