![来自不同行的 awk](https://linux22.com/image/121929/%E6%9D%A5%E8%87%AA%E4%B8%8D%E5%90%8C%E8%A1%8C%E7%9A%84%20awk.png)
我正在尝试从不断更新的文件中提取一些数据,并且我已经弄清楚如何使用 grep 过滤两个字符串。输出如下:
! 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
现在我想做的是从这些行中提取数字,如下所示:从以 ! 开头的行中提取数字。我想要第 5 列中的数字,从 grep 输出的下一行开始,我想要第 6 列中的数字。接下来,我希望将这些数字作为两个独立的列写入单独的文件中,如下所示:
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解决方案:
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