如何在Bash中提取grep结果里每个文件的最后一行?
提取grep多文件输出中每个文件的最后一行
刚好遇到过类似的需求,用awk就能完美解决,先给你直接上可行的方案,再解释细节:
核心解决方案:Awk按文件名追踪最后一行
如果你的grep输出已经保存到文件里(比如grep_output.txt),直接运行:
awk -F': ' '{saved[$1] = $0} END{for (f in saved) print saved[f]}' grep_output.txt
要是你想直接处理grep的实时输出,用管道连起来就行:
grep [你的grep匹配规则] *.out | awk -F': ' '{saved[$1] = $0} END{for (f in saved) print saved[f]}'
为什么这个命令管用?
-F': ':把每行的分隔符设为:加空格,这样$1就是文件名(比如re0_400.out),$0是整行内容{saved[$1] = $0}:用文件名作为数组的键,每次遇到同一文件的行,就用新行覆盖数组里旧的值——处理完所有行后,数组里每个键对应的就是该文件的最后一行END{...}:等所有行都处理完,遍历数组把每个文件的最后一行打印出来
进阶:保持文件的原始出现顺序
上面的命令输出顺序是awk数组的默认顺序,不一定和原输出里文件出现的顺序一致。如果你要严格按原顺序输出,稍微改一下代码:
awk -F': ' '{ if (!($1 in saved)) order[++count] = $1 saved[$1] = $0 } END { for (i=1; i<=count; i++) print saved[order[i]] }' grep_output.txt
这个版本会记录每个文件第一次出现的顺序,最后按这个顺序输出,完全匹配原输出的文件先后。
其他备选方案(不推荐,但可以参考)
如果不想用awk,也可以用sort配合awk的方式,但步骤更繁琐:
grep [你的规则] *.out | sort -t':' -k1,1 | awk 'prev!=$1{if(prev)print line; prev=$1} {line=$0} END{print line}'
不过还是第一个awk方案最简洁高效,推荐用它。
内容的提问来源于stack exchange,提问作者Joonho Park
相关产品推荐
相关产品推荐

