来自不同行的 awk

来自不同行的 awk

我正在尝试从不断更新的文件中提取一些数据,并且我已经弄清楚如何使用 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

相关内容