我是 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
和) 。但这没有多大意义——除非你有一个重复的模式,即标题、五行数据、另一个标题、另外五行数据等——如果是这样的话,你真的需要解释一下。如果这就是你想做的,那你为什么要用 而不是 来做呢?$6
z
~
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 和 zcounter > 1
。请注意,这不是测试counter > 0
或counter >= 1
,因此它会跳过标题后的第 1 行,并打印第 2、3、4、5 和 6 行。counter == 6 { counter = 0 }
表示当counter
达到 6 时,我们就完成了这个“主题”,所以我们将其设置counter
为零。counter > 0 { counter++ }
简单地说,只要我们处于一个“主题”中,我们就应该counter
为每一行增加(加一)。