私は常に更新されているファイルからいくつかのデータを抽出しようとしていましたが、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==n
v
- 最初のキー番号と現在のレコード番号があり、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