日志示例:

2018-01-01 11:30:22 xxx Parsing xxx
2018-01-01 11:30:23 driver queryId=<xxx> Parsing command: select *
from table
limit 10
2018-01-01 11:30:25 Parsing completed
2018-01-01 11:30:28 xxxxxx
2018-01-01 11:30:40 driver queryId=<xxx> Parsing command: select * from table group by column
2018-01-01 11:30:45 Parsing completed
2018-01-01 11:30:51 xxxxxx
2018-01-01 11:30:52 xxx Parsing xxx
2018-01-01 11:30:54 driver queryId=<xxx> Parsing command: select

*
from table

order by column

limit 20
2018-01-01 11:30:56 Parsing completed
2018-01-01 11:30:59 xxxxxx

我想删除“parsing command:”和“2018”匹配模式之间的新行,输出应该只包含与模式匹配的单词。
解析示例:
2018-01-01 11:30:54 driver queryId=<xxx> Parsing command: select

*
from table

order by column

limit 20
2018-01-01 11:30:56 Parsing completed

上述示例的输出应为,
select * from table order by column limit 20

最佳答案

下面是一个非常简短的使用perl而不是sed/awk的解决方案:

perl -ne 's/\n/ /; print +(s/^.*Parsing command: // .. /^2018/ or next) =~ /E/ ? "\n" : $_' input.log

想法是:
我们循环输入行(-n)。对于每一行,我们执行代码(-e ...):
首先,我们用空格(s/\n/ /)替换换行符。
然后我们检查一个COND1 .. COND2条件,这对于cond1和cond2之间的所有行都是正确的。
我们的第一个条件是替换s/^.*Parsing command: //,如果它设法删除以Parsing command:结尾的输入行的某些前缀,则该条件为真。这是我们射程的开始。
我们的第二个条件是match/^2018/,如果输入行以2018开头,则为true。这是我们射程的终点。
如果这个检查失败,我们就跳到下一个输入行(... or next)。对于其余代码,我们只考虑范围内的行。
..返回的值是一个序列号。范围中的最后一行附加了E0。我们检查/E/以排除范围的最后一行(以2018开头的那一行),因为我们不想打印它。
如果我们在最后一行,我们只输出一个换行符("\n"),否则我们打印该行符(最后一个换行符从第一个换行符转换为空格)。

关于linux - Sed/awk-如何删除开始模式和结束模式之间的换行符。,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48367255/

10-14 04:57