关于regex:sed:返回最后一次出现的匹配,直到文件结尾

sed: return last occurrence match until end of file

使用sed,如何返回匹配的最后一次出现直到文件结束?
(仅供参考)

到目前为止,我已经尝试过:

1
sed -n '/ Statistics |/,$p' logfile.log

从第一个匹配开始返回所有行(几乎整个文件)

我也尝试过:

1
2
$linenum=`tail -400 logfile.log | grep -n" Statistics |" | tail -1 | cut -d: -f1`
sed"$linenum,\\$!d" logfile.log

这行得通,但不能在一个命令中通过ssh连接工作,实际上需要全部都放在一个管道中。

日志文件的格式如下:

(有些统计信息标头每分钟都有写入日志文件的子数据,此命令的目的是返回最新的统计信息标头以及标头之后发生的任何相关错误)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

紧急行动

退货需要为:

1
2
3
4
Statistics |
   Stuff
Error: error type one
Error: error type two

如果您有tac可用:

1
tac INPUTFILE | sed '/^Statistics |/q' | tac


您的示例脚本在Statistics之前有一个空格,但是您的示例数据似乎没有。它有一个正则表达式,它假设统计信息位于行的开头;调整是否正确。

1
sed -n '/^Statistics |/h;/^Statistics |/!H;$!b;x;p'

当您看到统计信息时,请用当前行(h)替换保留空间。否则,请附加到保留空间(h)。如果我们不在文件末尾,请在此处停止(b)。在文件末尾,打印出保留空间(x检索保留空间的内容; p打印)。

sed脚本中,命令可选地以"地址"为前缀。最常见的是这是一个正则表达式,但也可以是行号。地址/^Statistics |/选择与正则表达式匹配的所有行; /^Statistics |/!选择与正则表达式不匹配的行;和$!匹配文件中最后一行以外的所有行。没有明确地址的命令将对所有输入行执行。

编辑详细解释脚本,然后添加以下内容。

请注意,如果您需要使用ssh将其传递给远程主机,则将需要其他级别的引用。如果过于复杂,一种可能的解决方法是将此脚本存储在远程主机上,只需ssh remotehost path/to/script。另一个可能的解决方法是更改??寻址表达式,以使它们不包含任何感叹号(在命令行中,例如Bash中,这是有问题的)。

1
sed -n '/^Statistics |/{h;b};H;${x;p}'

这也更简单!

如果您的ssh管道的stdin没有与其他事情捆绑在一起,则第三个可能的解决方法是从本地主机中引入脚本。

1
2
echo '/^Statistics |/h;/^Statistics |/!H;$!b;x;p' |
ssh remotehost sed -n -f - file


这可能对您有用:

1
2
3
4
5
sed '/Statistics/h;//!H;$!d;x' file
Statistics |
   Stuff
Error: error type one
Error: error type two


如果您对awk解决方案感到满意,则可以使用此方法(除了获得额外的空白行):

1
2
awk '/^Statistics/ { buf ="" } { buf = buf"\
" $0 } END { print buf }'
input.txt

这可能也可以用,由上面其他人给出的sed解决方案稍微简单一些:

1
sed -n 'H; /^Statistics |/h; ${g;p;}' logfile.log

输出:

1
2
3
4
Statistics |
   Stuff
Error: error type one
Error: error type two

1
sed ':a;N;$!ba;s/.*Statistics/Statistics/g' INPUTFILE

应该工作(GNU sed 4.2.1)。

它将整个文件读取为一个字符串,然后用Statistics替换从开始到最后一个Statistics(包括单词)的所有内容,并打印剩余的内容。

高温超导