別の行から来た

別の行から来た

私は常に更新されているファイルからいくつかのデータを抽出しようとしていましたが、grepを使用して2つの文字列をフィルタリングする方法を見つけました。出力は次のとおりです。

!    total energy              =   -9744.24963670 Ry
     convergence has been achieved in 188 iterations
!    total energy              =   -9744.30001681 Ry
     convergence has been achieved in 140 iterations
!    total energy              =   -9744.33953891 Ry
     convergence has been achieved in 155 iterations
!    total energy              =   -9744.36584201 Ry
     convergence has been achieved in 164 iterations
!    total energy              =   -9744.37925372 Ry
     convergence has been achieved in 154 iterations
!    total energy              =   -9744.39185493 Ry
     convergence has been achieved in 153 iterations
!    total energy              =   -9744.39836617 Ry
     convergence has been achieved in 160 iterations

今やりたいことは、次のようにこの行から数字を抽出することです。 ! で始まる行から数字を抽出します。 grep 出力の次の行から始めて、列 5 の数字が必要で、列 6 の数字が必要です。次に、この数字を次のように2つの別々の列で別々のファイルに書きたいと思います。

188 -9744.24963670
140 -9744.30001681
155 -9744.33953891
164 -9744.36584201

私はawkを使用してすべてのgrep結果を繰り返し、奇数行を見て列5を印刷し、偶数行を見て列6を印刷したいと思います。しかし、どうすればいいのかわかりません。

個々の結果を個別に変数として抽出してみました。

var1=$(grep '!' input.file | awk '{print $5}')

そして

var2=$(grep 'convergence has been achieved' input.file | awk '{print $6}')

それからファイルに書き込もうとします。

echo $var1 $var2 > data.dat

しかし、結果は予想とは異なります。

188                                                                                                                                                                                             
140
155
164
154
153
160 -9744.24963670
-9744.30001681
-9744.33953891
-9744.36584201
-9744.37925372
-9744.39185493
-9744.39836617

上記の形式で書く方法がわかりません。また、ファイルは継続的に更新されるため、このコードはwhileループまでおよび終了条件と組み合わせられたと想像されます(最後の部分を実行する方法を知っています)。

はっきりと説明してほしい!

答え1

アッ解決策:

awk 'v && NR==n{ print $6,v > "result.txt" }/^!/{ v=$5; n=NR+1 }' file
  • <condition1> { <statement> ... }<condition2>{ <statement> ... }- 該当するステートメントの条件は継続的に評価されます。

  • /^!/{ v=$5; n=NR+1 }- 次の行が見つかった場合!- 5番目のフィールド値をキャプチャし$5、次の行番号を予約しますNR+1(変数に割り当てられますn)。

  • v && NR==nv- 最初のキー番号と現在のレコード番号があり、NR必要な場合「次の行番号」 n- 値をファイルとして印刷result.txt


文書のresult.txt内容:

188 -9744.24963670
140 -9744.30001681
155 -9744.33953891
164 -9744.36584201
154 -9744.37925372
153 -9744.39185493
160 -9744.39836617

答え2

paste独自のソリューションを使用するには、結果を並べて印刷するコマンドが必要です。

paste <(echo "$var2") <(echo "$var1") #or better via 'printf'
paste <(printf '%s' "$var2") <(printf '%s' "$var1")

ただし、単純なawkコマンドを使用すると、次のことができます。

awk '/\!/{C5=$5;getline; print $6, C5 >"output.txt"}' infile

関連情報