regex - sed:返回最后一次匹配直到文件结束

标签 regex bash sed

如何使用 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/

相关文章:

bash - 检测单色图像中最右边黑色像素的 x 值?

regex - sed - 如何获得段落的前两句?

linux - 在unix中为两个字段添加双引号

linux - 对发生模式不匹配的文件进行行编号

regex - bash,在冒号前提取字符串

c# - 在 C# 中获取重叠的正则表达式匹配

bash - 以不将其值保存到 bash 历史记录中的方式设置环境变量(密码)

python - 如何在驻留在不同路径的包上使用 mod 选项 "-m"运行 Python3?

ruby - 用于验证长而复杂的 dns 目标的正则表达式

javascript - 如何实现条件中的任意数字?