使用sed
,我想打印文件的最后一个匹配行。我碰到
但是,我只想要匹配的线本身,而不是任何范围的线。使用该页面,我实际上想出了一个有效的命令
$ sed '/out_time=/h; $!d; x' progress.txt
out_time=00:00:07.720000
问题是为什么这会起作用,或者换句话说,这个命令中发生了什么。sed
如果存在,还包括一个更简单的命令。
使用sed
,我想打印文件的最后一个匹配行。我碰到
但是,我只想要匹配的线本身,而不是任何范围的线。使用该页面,我实际上想出了一个有效的命令
$ sed '/out_time=/h; $!d; x' progress.txt
out_time=00:00:07.720000
问题是为什么这会起作用,或者换句话说,这个命令中发生了什么。sed
如果存在,还包括一个更简单的命令。
很简单,这些是在每一行(循环)上运行的三个独立命令:
h
命令将当前保持缓冲区替换为包含out_time=
.$!d
删除任何不是最后一行并重新开始下一个循环。x
命令交换保持和模式缓冲区。效果是最后out_time=
一行被放置在保持缓冲区中,并且唯一通过$!d
过滤器逃逸的行(文件的最后一行)在打印之前与该保持缓冲区交换。
将其视为以下几行的程序:
for every line in file:
if line contains "out_time=":
holdbuff = line
if line is not last line of file:
continue for loop
swap line and holdbuff
print line
当然,如果您拥有适合这项工作的正确工具,则可以避免整个折磨过程:
grep 'out_time=' progress.txt | tail -1
我想这可能被认为更简单:
sed -n '/out_time=/h; ${x;p;}' progress.txt
也可以写成:
sed -n '/out_time=/h; $x; $p' progress.txt
在所有这些中,sed
只是在保持空间中保存了一条匹配行,因此当它到达文件末尾时,它找到的最后一个匹配项是在保持空间中。此时,它将保持空间拉入模式空间,然后打印它。
一个很晚的答案,没有使用任何管道awk
(有人提到了正确的工具......):
awk '/out_time=/{last=$0} END{print last}' progress.txt
解释:
/$PAT/{...}
: 将匹配的事件保存到变量last
中,覆盖之前的事件END{...}
:退出程序时执行块,在这种情况下打印的值last