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