我有一个标准格式的日志文件,例如:
31 Mar - Lorem Ipsom1
31 Mar - Lorem Ipsom2
31 Mar - Lorem Ipsom3
我要实现的替换是 31*31 到 31,所以我最终会得到一个只有最后一行的日志,在这个例子中它看起来像:
31 Mar - Lorem Ipsom3
我希望在没有 perl 的定制 linux 机器上执行它。 我试过像这样使用 sed:
sed -i -- 's/31*31/31/g' /var/log/prog/logFile
但它什么也没做.. 也欢迎任何涉及忍者 bash 命令的替代方法。
最佳答案
一种只保留最后一行匹配模式的方法是
sed -n '/^31/ { :a $!{ h; n; //ba; x; G } }; p' filename
工作原理如下:
/^31/ { # if a line begins with 31
:a # jump label for looping
$!{ # if the end of input has not been reached (otherwise the current
# line is the last line of the block by virtue of being the last
# line)
h # hold the current line
n # fetch the next line. (note that this doesn't print the line
# because of -n)
//ba # if that line also begins with 31, go to :a. // attempts the
# most recently attempted regex again, which was ^31
x # swap hold buffer, pattern space
G # append hold buffer to pattern space. The PS now contains
# the last line of the block followed by the first line that
# comes after it
}
}
p # in the end, print the result
这避免了多行正则表达式的一些问题,例如在一行中间开始或结束的匹配。它也不会丢弃两个匹配行 block 之间的行,并保留每个 block 的最后一行。
关于regex - 来自终端的 Sed 正则表达式字符串替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29367276/