如何使用 sed 返回匹配项的最后一次出现,直到文件结束? (仅供引用,这已被简化)
到目前为止我已经尝试过:
sed -n '/ Statistics |/,$p' logfile.log
返回从第一个匹配开始的所有行(几乎整个文件)
我也试过:
$linenum=`tail -400 logfile.log | grep -n " Statistics |" | tail -1 | cut -d: -f1`
sed "$linenum,\$!d" logfile.log
这行得通,但不能在一个命令中通过 ssh 连接工作,确实需要将其全部放在一个管道中。
日志文件格式如下:
(每分钟都有统计头和子数据写入日志文件,此命令的目的是返回最新的统计头以及头后发生的任何相关错误)
Statistics |
Stuff
More Stuff
Even more Stuff
Statistics |
Stuff
More Stuff
Error: incorrect value
Statistics |
Stuff
More Stuff
Even more Stuff
Statistics |
Stuff
Error: error type one
Error: error type two
结束
返回需要是:
Statistics |
Stuff
Error: error type one
Error: error type two
最佳答案
您的示例脚本在 Statistics 之前有一个空格,但您的示例数据似乎没有。这有一个正则表达式,它假设 Statistics 在行的开头;如果不正确,请进行调整。
sed -n '/^Statistics |/h;/^Statistics |/!H;$!b;x;p'
当您看到统计信息时,将保留空间替换为当前行 (h
)。否则,追加到保留空间 (H
)。如果我们不在文件末尾,请在此处停止 (b
)。在文件末尾,打印出保留空间(x
检索保留空间的内容;p
打印)。
在 sed
脚本中,命令可以选择以“地址”作为前缀。最常见的是正则表达式,但也可以是行号。地址/^Statistics |/
选择匹配正则表达式的所有行; /^Statistics |/!
选择与正则表达式不匹配的行; $!
匹配文件中除最后一行以外的所有行。对所有输入行执行没有显式地址的命令。
编辑更详细地解释脚本,并添加以下内容。
请注意,如果您需要使用 ssh
将其传递给远程主机,您将需要额外的引用级别。如果它变得太复杂,一种可能的解决方法是将此脚本存储在远程主机上,并且只是 ssh remotehost path/to/script
。另一种可能的解决方法是更改寻址表达式,使它们不包含任何感叹号(这些在命令行上是有问题的,例如在 Bash 中)。
sed -n '/^Statistics |/{h;b};H;${x;p}'
这也比较简单!
第三种可能的解决方法是,如果您的 ssh 管道的 stdin 没有被其他东西占用,则从您的本地主机通过管道输入脚本。
echo '/^Statistics |/h;/^Statistics |/!H;$!b;x;p' |
ssh remotehost sed -n -f - file
关于regex - sed:返回最后一次匹配直到文件结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7724778/