在文件中打印一行的最后一列

193
我有一个正在不断被写入/更新的文件,我想要找到包含特定单词的最后一行,然后打印该行的最后一列。
该文件看起来像这样。随着时间的推移,将会追加更多A1/B1/C1行。
A1 123 456
B1 234 567
C1 345 678
A1 098 766
B1 987 6545
C1 876 5434

我尝试使用

tail -f file | grep A1 | awk '{print $NF}'

有一个值为766,但我没有任何输出。

有什么方法可以解决这个问题吗?

11个回答

283

由于缓冲区的原因,您看不到任何内容。只有在有足够多的行或到达文件末尾时,输出才会显示出来。tail -f 意味着等待更多的输入,但是在file中没有更多的行,因此管道到grep从未关闭。

如果从tail中省略-f,则立即显示输出:

tail file | grep A1 | awk '{print $NF}'

@EdMorton 当然是正确的。 Awk 也可以搜索 A1,这将缩短命令行为:

tail file | awk '/A1/ {print $NF}'

或不显示尾部,显示所有包含A1的行的最后一列

awk '/A1/ {print $NF}' file

感谢@MitchellTracy的评论,tail命令可能会错过包含 A1 的记录,因此您将得不到任何输出。可以通过交换 tailawk 命令来解决这个问题,先搜索整个文件,然后再显示最后一行:
awk '/A1/ {print $NF}' file | tail -n1

20
awk 可以执行自己的正则匹配,所以你永远不需要同时使用 grep 和 awk。"grep A1 | awk '{print $NF}'" 应该简化为 "awk '/A1/{print $NF}'"。此外,如果你没有使用 tail -f,那么完全不需要使用 tail 命令,可以直接使用:awk '/A1/{f=$NF} END{print f}' file。 - Ed Morton
1
这并不完全正确,因为列可能不会出现在原始的 tail 窗口中。除非你知道它将以某种频率出现,否则最好使用 awk '/A1/ {print $NF}' file | tail -n1 更安全。 - Mitchell Tracy

41

要打印一行的最后一列,只需使用$(NF):

awk '{print $(NF)}' 

1
为什么不直接使用$NF - x-yuri

14

使用 awk 的一种方法:

tail -f file.txt | awk '/A1/ { print $NF }'

我曾认为这是发布的问题的正确解决方案(+1!),但现在我发现我不理解这个问题。 OP想要文件的最后一行的最后一个字段,但如果您使用tail -f,则没有LAST LINE。也许他的意思是当前文件中的最后一行,在这种情况下,请参阅我的其他评论。 - Ed Morton
非常好而且简单。点赞!对于awk的神秘语法,我要点踩 :) - stamster
awk的语法现在可能看起来有点神秘,但它确实领先于其时代。在1977年(awk诞生时),C语言只是一个5岁的幼儿,而C++则只是Bjarne的想象。这是我唯一使用的一种语言,其中将整个程序包含在命令行参数中是很正常的!虽然我可能有偏见,因为我一直有点awk-ward。 ;) - Tyler

12

你可以使用一些管道操作而无需使用 awk 完成这个任务。

tac file | grep -m1 A1 | rev | cut -d' ' -f1 | rev

这解决了你的问题,但它并没有真正使用awk。希望对你来说足够好了。 - miono

4
也许这个可以工作吗?
grep A1 file | tail -1 | awk '{print $NF}'

2
你可以使用awk完成所有这些操作:
<file awk '$1 ~ /A1/ {m=$NF} END {print m}'

1
你不需要使用split()和数组,只需保存最后一个字段并打印它:awk '/A1/{f=$NF} END{print f}' 文件 - Ed Morton

2

这里并非实际问题,但可能会帮助某些人:我正在执行awk "{print $NF}",请注意引号错误。应该是awk '{print $NF}',以便Shell不扩展$NF


2
使用 Perl
$ cat rayne.txt
A1 123 456
B1 234 567
C1 345 678
A1 098 766
B1 987 6545
C1 876 5434


$ perl -lane ' /A1/ and $x=$F[2] ; END { print "$x" } ' rayne.txt
766

$

看起来太复杂了,只需执行 perl -lane 'print $F[2] if /A1/' rayne.txt 即可。 - Hi-Angel
1
@Hi-Angel,问题要求找到A1的最后一次出现。你的答案会打印所有匹配项。顺便说一句,如果你喜欢我的答案,请点赞。 - stack0114106

1
使用awk命令,将字段分隔符-F设置为一个空格。使用模式$1=="A1"和动作{print $NF},这将打印第一个字段为"A1"的每个记录中的最后一个字段。将结果传输到tail,并使用选项-n 1仅显示最后一行。

0
执行此操作于文件:
awk 'ORS=NR%3?" ":"\n"' filename

你会得到你想要的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接