如何使用awk打印最后两列


106

我只需要打印最后两列。


6
不太确定为什么要进行87次投票,至少可以举一个例子加以改进。
Arj

可能是因为该问题本质上非常简单,并且没有示例就很容易理解,这种情况很少见,但是在这种情况下它似乎可以解决。我认为这里的问题不是缺乏信息,而是更多地表明缺乏独立研究。
DryLabRebel

这个问题也是这个问题的重复。
DryLabRebel

这回答了你的问题了吗?在awk中打​​印倒数第二列/字段
DryLabRebel

Answers:


194

您可以使用NF设置为输入记录中字段总数的变量:

awk '{print $(NF-1),"\t",$NF}' file

假定您至少有2个字段。


1
您需要一个逗号-因为我们今天很挑剔:空格将字段连接在一起,逗号将打印语句中的字段分隔开。那将合并这两个领域
Jim Mcnamara 2010年

18
现在,您正在打印“ field-OFS-tab-OFS-field”。它应该是awk '{print $(NF-1) "\t" $NF}' fileor awk '{print $(NF-1), $NF}' fileawk 'BEGIN{OFS="\t"} {print $(NF-1), $NF}' file
暂停,直到另行通知。

只需添加到以往的评论,与使用问题'{print $x,"\t",$y}'是,AWK解释每个逗号分隔的变量,因为它自己的领域,这样的结果实际上是field1<space><tab><space>field2,(因为它会默认使用空格分隔符),而不是field1<tab>field2它大概是什么您正在期待。使用输出字段分隔符(OFS)几乎总是您想要的。
DryLabRebel

13
awk '{print $NF-1, $NF}'  inputfile

注意:仅当至少存在两列时,此方法才有效。在只有一列的记录上,您会得到一个虚假的信息"-1 column1"


3
尝试看看。它确实可以在Solaris 9 awk和nawk中运行。备选方案是$(NF-1)
吉姆·麦克纳马拉

1
@coaddict-我猜您尚未使用其他awk实现。旧的awk行为已经(可能是错误地)提出来了。我没有gawk可以测试-这可能是您所引用的。因此,我不确定您的评论为何被拒绝。开箱即用的Linux awk通常是gawk。我将进行测试并发回。同时尝试Soalris或HPUX或DGX或其他工具,以了解我所说的老awk的含义。
吉姆·麦克纳马拉

6
您可能因为尝试过而被欺骗了,以为它起作用了echo 1 2 3 | awk ...$NF-1($NF) - 1在每一个awk实施。
Stephane Chazelas 2014年

“一个真实的Awk”源代码在yacc语法上有40多个冲突,考虑到A在awk中的含义,这具有讽刺意味。不同版本的awk解析情况有所不同?大惊喜!
卡兹(Kaz)2014年

1
@THESorcerer,尝试echo '5 4 3 2 1' | awk '{print $NF-1,$NF; print $(NF-1), $NF}'-或任何其他倒数第二个字段不少于最后一个字段的输入。
glenn jackman

6

@jim mcnamara:尝试在周围使用括号NF,即 $(NF-1)和,$(NF)而不是$NF-1$NF(在Mac OS X 10.6.8上适用于FreeBSD awkgawk)。

echo '
1 2
2 3
one
one two three
' | gawk '{if (NF >= 2) print $(NF-1), $(NF);}'

# output:
# 1 2
# 2 3
# two three

我们之前已经考虑过()。我以为我们正在讨论原始的旧awk行为来自何处。
jim mcnamara 2013年

+1为明确的答案$(NF-1)-至少比答案更可移植$NF-1; 绝对不那么模棱两可。$(NF)不过,这太过分了-只会$NF这么做。防止少于2列的行也是值得的,因为对于单行的行,您将获得两次第一列值,而对于零行的行(即,空行),由于尝试,awk命令将完全失败访问索引为-1的字段。
mklement0 2014年

1

使用gawk会出现问题:

 gawk '{ print $NF-1, $NF}' filename
1 2
2 3
-1 one
-1 three
# cat filename
1 2
2 3
one
one two three

我只是将gawk放在Solaris 10 M4000上:因此,gawk是$ NF-1与$(NF-1)问题的问题。下一个问题POSIX说什么?每:

http://www.opengroup.org/onlinepubs/009695399/utilities/awk.html

没有一种方向或另一种方向。不好。gawk表示减法,其他awk表示字段号或减法。嗯。


1
样本输入文件的前两行没有帮助,因为它们在任何一种行为下都会产生相同的输出。您能否再次确认Solaris awk在这种情况下的行为确实不像gawk?
mklement0 2014年

至于您到awk规范的链接:使用的轶事参数$(NF-1)是,在规范中计算字段索引的两个示例都使用该形式:$(NF-1)$(NF+2)。然后是“ awk中的表达式”部分,其中列出的$expr优先级比更高expr - expr。既然NF是表达式本身,$NF-1则应求值为($NF)-1。毕竟,即使是IF,实际上也确实有awk的实现将其评估$NF-1$(NF-1),从中吸取的教训是,使用$(NF-1)是安全且可移植的选择。
mklement0

0

试试这个

$ cat /tmp/topfs.txt
/dev/sda2      xfs        32G   10G   22G  32% /

awk print last column
$ cat /tmp/topfs.txt | awk '{print $NF}'

awk print before last column
$ cat /tmp/topfs.txt | awk '{print $(NF-1)}'
32%

awk - print last two columns
$ cat /tmp/topfs.txt | awk '{print $(NF-1), $NF}'
32% /

0

请尝试此操作以考虑所有可能的情况:

awk '{print $(NF-1)"\t"$NF}'  file

要么

awk 'BEGIN{OFS="\t"}' file

要么

awk '{print $(NF-1), $NF} {print $(NF-1), $NF}' file
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.