web-dev-qa-db-ja.com

awk、sedを使用して特定のパターンを持つ行の一部を抽出する

Awk/sedオペレーターについて質問があります。次の一連の行が繰り返されている大きなファイルがあります

Expression loweWallrhoPhi :  sum=-6.97168e-09
Expression leftWallrhoPhi :  sum=6.97168e-09
Expression lowerWallPhi :  sum=-5.12623e-12
Expression leftWallPhi :  sum=5.12623e-12
Expression loweWallrhoUSf :  sum=-6.936e-09
Expression leftWallrhoUSf :  sum=6.97169e-09
Expression lowerWallUSf :  sum=-5.1e-12
Expression leftWallUSf :  sum=5.12624e-12

合計後の値をそれぞれ別のファイルに抽出したい。一度にそれを行うことは可能ですか?

Grepコマンドで:

grep -oP 'sum=\K.*' inpufile > outputfile

-P(Perl-regexp)パラメータを指定したgrepは、以前に一致した文字を無視するために使用する\Kをサポートします。

Awkコマンドで:

awk -F"=" '{print $NF}' inputfile > outputfile

Awk NFは、レコード/行のフィールドの総数を示します。したがって、その最後の値は、レコード/行の最後のフィールド番号です。

Sedコマンドで:

sed 's/^.*sum=//' inpufile > outputfile

^.*=sum行の先頭(.*)と最後の文字(^)の間のすべての文字(sum=)を空白文字に置き換えます。

結果:

-6.97168e-09
6.97168e-09
-5.12623e-12
5.12623e-12
-6.936e-09
6.97169e-09
-5.1e-12
5.12624e-12

各値を個別のファイルに保存する場合は、上記のコマンドをwhileループで使用します。

while read line; do
    echo "$line" | grep -oP 'sum=\K.*'     > $(echo "$line" |awk '{print $2}');
   #echo "$line" | awk -F"=" '{print $NF}' > $(echo "$line" |awk '{print $2}');
   #echo "#line" | sed 's/^.*sum=//'       > $(echo "$line" |awk '{print $2}');
done < file
27
αғsнιη

私が正しく理解している場合は、=の後にある値のみを取得し、これらの値を2番目のフィールド(?)に基づいて個別のファイルに保存します。私が正しいなら、次のようなことを試してください:

$ awk -F'[ =]' '{print $6>"file_"$2".txt"}' file

結果:

$ ls -1
  file_leftWallPhi.txt
  file_leftWallUSf.txt
  file_leftWallrhoPhi.txt
  file_leftWallrhoUSf.txt
  file_loweWallrhoPhi.txt
  file_loweWallrhoUSf.txt
  file_lowerWallPhi.txt
  file_lowerWallUSf.txt

$ cat  file_leftWallPhi.txt
  5.12623e-12
6
jimmij

sedで実行できます

sed -E 's/^.* (\S+)\s*:.*=(\S+)/echo "\2" > "\1".txt/' file | bash

スクリプトは次の2つの部分を見つけます。

  1. スペースと:の間で、いくつか(0以上)の非スペースシンボルを含める必要があります。
  2. =;の後のいくつか(0以上)の非スペース記号

パイプを介してbashに転送された実行中のコマンドからフォーマットします

1
Costas