AWK 打印行并丢弃其中的一些

AWK 打印行并丢弃其中的一些

我是 AWK 新手。我在一个巨大的文件中有以下主题。

~ Gradients ~
~   x               y            z      ~
~~ 
~ H         1      0.00781      0.00108      0.00038 ~
~ H         2      0.01271     -0.01507      0.02839 ~
~ C         1     -0.05015     -0.01803      0.01588 ~
~ O         1      0.01733      0.03089     -0.04611 ~
~ O         2      0.01230      0.00114      0.00147 ~

我需要提取这些数字(xyz):

0.00781      0.00108      0.00038
0.01271     -0.01507      0.02839
-0.05015     -0.01803      0.01588
0.01733      0.03089     -0.04611 
0.01230      0.00114      0.00147

我写了以下脚本:

awk '/z ~/ {for(i=-2; i<=3; i++) {getline; print $4, $5, $6}}' filename

但是由于“~~”行,它给了我空白行。

我想忽略此行并仅获取 xyz 列

xyz
xyz
xyz
xyz 

等等,没有任何空行......

有人能帮帮我吗?

答案1

你能解释得更清楚吗确切地你想做什么?看起来你正试图在包含文字后跟 的行之后的接下来六行中打印 x、y 和 z 值( $4$5和) 。但这没有多大意义——除非你有一个重复的模式,即标题、五行数据、另一个标题、另外五行数据等——如果是这样的话,你真的需要解释一下。如果这就是你想做的,那你为什么要用 而不是 来做呢?$6z~for(i=-2; i<=3; i++)for(i=1; i<=6; i++)

这不是一个好的使用方法getline

如果我正确理解了你的目的,你所需要的就是

awk 'NF==7 {print $4, $5, $6}' filename

这将打印每行有七个字段的第 4、第 5 和第 6 个字段(x、y 和 z),并忽略其他所有内容。

答案2

您的问题令人困惑,因为您的数据似乎有一个以 结尾的标题行z      ~ ,而您的命令似乎在搜索/z ~/,因此它们不应该匹配。但实际上可能在两个地方都存在。zTab~

为简单起见,我将使用/z *~/, 来匹配z, 后跟任意数量的空格,后跟~。继续使用适合您的任何搜索字符串。

您已在注释中澄清,您想要在包含 的标题行之后打印第 2、3、4、5 和 6 行的 x、y 和 z 值。z   ~以下是在 中执行此操作的方法awk

awk '
        /z *~/          { counter=1; next }
        counter > 1     { print $4, $5, $6 }
        counter == 6    { counter = 0 }
        counter > 0     { counter++ }
    ' filename
  • /z *~/ { counter=1; next }表示,当我们看到包含 的行时z   ~,我们将计数器设置为 1。这将用于计算接下来的六行。使用命令next不对此行进行进一步处理 — 我们甚至不想考虑打印标题行的可能性。
  • counter > 1 { print $4, $5, $6 }从 行打印 x、y 和 z counter > 1。请注意,这不是测试counter > 0counter >= 1,因此它会跳过标题后的第 1 行,并打印第 2、3、4、5 和 6 行。
  • counter == 6 { counter = 0 }表示当counter达到 6 时,我们就完成了这个“主题”,所以我们将其设置counter为零。
  • counter > 0 { counter++ }简单地说,只要我们处于一个“主题”中,我们就应该counter为每一行增加(加一)。

相关内容