Regex 如何打印与最后一行的第一个字段匹配的所有行

Regex 如何打印与最后一行的第一个字段匹配的所有行,regex,shell,command-line,awk,sed,Regex,Shell,Command Line,Awk,Sed,这两天我一直在努力。我读了很多教程,学到了很多新东西,但到目前为止,我还没能达到我想要达到的目标。假设这是命令行输出: Johnny123 US 224 Johnny123 US 145 Johnny123 US 555 Johnny123 US 344 Robert UK 4322 Robert UK 52 Lucas FR 344 Lucas FR 222 Lucas FR 8945 我想打印与“最后一行的第一个字段(Lucas)”匹配的行

这两天我一直在努力。我读了很多教程,学到了很多新东西,但到目前为止,我还没能达到我想要达到的目标。假设这是命令行输出:

Johnny123   US  224
Johnny123   US  145
Johnny123   US  555
Johnny123   US  344
Robert  UK  4322
Robert  UK  52
Lucas   FR  344
Lucas   FR  222
Lucas   FR  8945
我想打印与“最后一行的第一个字段(Lucas)”匹配的行。

所以,我想打印出:

Lucas   FR  344
Lucas   FR  222
Lucas   FR  8945
注:

  • 我要打印的内容每次都有不同的行数,所以我不能只返回最后3行
  • 第一个字段没有我可以用来打印的特定模式
或者如果你愿意的话

awk '{val[$1]=val[$1] $0 RS; key=$1} END{printf "%s", val[key]}' file

下面是使用
tac
awk
的另一种方法:

tac file | awk 'NR==1{last=$1}$1==last' | tac
Lucas   FR  344
Lucas   FR  222
Lucas   FR  8945
只有订单重要时才需要最后一个
tac

这可能适合您(GNU-sed):


在保留空间中存储具有重复键的行。更改键时,删除前面的行。在文件末尾打印出剩下的内容。

这同样有效:D.在哪里我可以了解复杂的sed命令(如下图)?@AvinashRaj将鼠标悬停在
sed
标记上,然后选择
info
信息页面中有许多链接。请为我推荐一个清晰描述sed循环、保持空间、图案空间和标签的工具。@EdMorton是的,我同意你的观点。请推荐关于数组、循环的awk教程。@AvinashRaj刚刚得到Arnold Robbins(gawk的提供者)的书《有效的awk编程,第三版》。太棒了。它起作用了。你能给我解释一下“{last=$1}$1==last”部分吗。我搜索了'NR==1',现在我明白了它的意思是一条记录,但剩下的代码呢?我只是想了解,如果我遇到了其他可以用awk解决的问题。@Sameh,不客气。当然,
last
只是一个变量,当第一列是第一行时,我们为它赋值(请记住,
tac
已经为我们反转了文件)<代码>$1==last是一个测试条件。如果这是真的,我们将打印这行。太好了!非常感谢你。最后一件事,这段代码将在一个在线工具中使用,因此它将大量运行。性能方面,哪一个更高效?您或Ed Morton的答案?@Sameh您可以使用生产文件中的一个运行这两个命令,并使用
time
命令(只需将
time
放在上面显示的命令前面,
time tac file…
),然后查看性能。我的猜测是,两者所用的时间应该相当长
tac
可能会快一点,因为它是一个
C
实用程序,用于反转文件,但我可能会偏向于我的答案<代码>:)。嗨,埃德。我记得你的答案是我收到的第一个工作答案。非常感谢你。顺便说一句,您的第一个代码不会打印任何内容,但第二个代码可以正常工作。此外,正如我在jaypal的回答中所问的,这段代码将用于在线工具中,因此它将大量运行。性能方面,哪一个更高效?您的代码还是jaypal的asnwer?您是否注意到在命令行中为第一个脚本指定了两次文件名?wrt性能-对于任何大小合理的文件,它们都会在眨眼之间运行,所以只需选择任何一个您在将来能够轻松支持、维护和增强的文件即可。我明白了。谢谢你的回复Ed。我不是在文件上运行这个。我直接在命令行的输出上运行它。所以我认为这就是为什么它现在对我不起作用的原因。对,第一个版本不能在管道输入上运行。
tac file | awk 'NR==1{last=$1}$1==last' | tac
Lucas   FR  344
Lucas   FR  222
Lucas   FR  8945
sed -nr 'H;g;/^(\S+\s).*\n\1[^\n]*$/!{s/.*\n//;h};$p' file