sed:返回上次出现的匹配,直到文件结束

f2s*_*f2s 8 regex bash sed

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

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

sed -n '/ Statistics |/,$p' logfile.log
Run Code Online (Sandbox Code Playgroud)

从第一场比赛开始返回所有线路(几乎整个文件)

我也尝试过:

$linenum=`tail -400 logfile.log | grep -n " Statistics |" | tail -1 | cut -d: -f1`
sed "$linenum,\$!d" logfile.log
Run Code Online (Sandbox Code Playgroud)

这可以工作但不能在一个命令中使用ssh连接,真的需要它在一个管道中.

日志文件的格式如下:

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

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
Run Code Online (Sandbox Code Playgroud)

EOF

返回需要是:

Statistics |
   Stuff
Error: error type one
Error: error type two
Run Code Online (Sandbox Code Playgroud)

tri*_*eee 15

您的示例脚本在统计信息之前有一个空格,但您的示例数据似乎没有.这有一个正则表达式,假设统计数据处于起始行; 调整,如果这是不正确的.

sed -n '/^Statistics |/h;/^Statistics |/!H;$!b;x;p'
Run Code Online (Sandbox Code Playgroud)

看到Statistics时,用当前行(h)替换保留空间.否则,附加到保留空间(H).如果我们不在文件的末尾,请停在这里(b).在文件末尾,打印出保留空间(x检索保留空间的内容; p打印).

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

编辑更详细地解释脚本,并添加以下内容.

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

sed -n '/^Statistics |/{h;b};H;${x;p}'
Run Code Online (Sandbox Code Playgroud)

这也有点简单!

第三种可能的解决方法,如果你的ssh管道的stdin与其他东西没有关系,那就是从本地主机管道脚本.

echo '/^Statistics |/h;/^Statistics |/!H;$!b;x;p' |
ssh remotehost sed -n -f - file
Run Code Online (Sandbox Code Playgroud)


gle*_*man 14

如果您有tac:

tac INPUTFILE | sed '/^Statistics |/q' | tac
Run Code Online (Sandbox Code Playgroud)