日志示例:
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/