Grep/awk/sed状态行匹配
我有一个日志文件,其中包含可以跨多行拆分的条目,我希望找到这些条目的所有实例 例如:Grep/awk/sed状态行匹配,awk,sed,grep,stateful,Awk,Sed,Grep,Stateful,我有一个日志文件,其中包含可以跨多行拆分的条目,我希望找到这些条目的所有实例 例如: AAA normal line BBB normal line XXX important line important line continuation 1 important line continuation 2 BBB normal line normal line continuation 1 AAA normal line XXX important line important line
AAA normal line
BBB normal line
XXX important line
important line continuation 1
important line continuation 2
BBB normal line
normal line continuation 1
AAA normal line
XXX important line
important line continuation 1
important line continuation 2
important line continuation 3
AAA normal line
所有条目都以代码开头(AAA、BBB、XXX等)。以代码XXX开头的行及其相关的续行是我感兴趣的行。连续行以空格开头,可以有任意数量的连续行。续行后面的行可以以任何代码开头
我认为这是一种“有状态”匹配(尽管可能无法通过这种方式解决)。。。ie:我希望行匹配模式XXX,然后所有紧跟其后的行都以空格开头(直到它们不匹配为止)
如何在跟踪日志文件的同时对此进行grep、sed或awk
更新:所需结果示例:
XXX important line
important line continuation 1
important line continuation 2
XXX important line
important line continuation 1
important line continuation 2
important line continuation 3
这个
awk
应该可以工作:
awk '/^[^ \t]/{p = ($1 == "XXX")} p' file
命令说明:
:如果一行不是以空格或制表符开头,则为条件/^[^\t]/
:启动操作块{
:如果第一列是p=($1==“XXX”)
,则将XXX
设置为p
,否则将其设置为1
0
:结束块}
:如果p
则打印行p==1
$1==XXX
时,p
将设置为1
,我们将继续打印行,直到p
再次变为0
。这可能对您有用(GNU-sed):
如果一行以XXX
开头,请打印它,然后提取下一行
如果该行以空格开头,则打印该行并提取下一行,然后重复
任何其他行都将被删除
注意:N
通常打印图案空间中的当前行,然后用下一行替换。这是sed中的正常循环,例如,sed''文件
将只打印文件。如果使用-n
选项,则不会进行隐式打印,因此:
sed -n '/^XXX/{:a;p;n;/^ /ba}' file
达到同样的效果
如果行的开头可能是选项卡或任何空白,请使用:
sed '/^XXX/{:a;n;/^\s/ba};d' file
预期产量是多少?同时展示你的尝试。sed或grep很简单(可能还有awk,我不太擅长awk)。想想看:你想要所有以“XXX”或“.”开头的行。@Beta不,我不想要。例如,我不希望在BBB行之后有续行。对不起,我的错误。在sed中还不算太糟糕,但您应该展示一些解决方案的尝试。@anubhava使用预期的输出进行了更新。我不知道sed或awk,所以不知道他们是否有能力解决这个问题。据我所知,没有办法用grep解决这个问题。谢谢,但这是怎么回事?将此从语法转换到awk用户指南的部分是很困难的。。。看起来您已经有了“以空格或制表符以外的内容开头的行”的正则表达式,然后应用一个表示“第一个字段等于“XXX”的输出行”的操作。如何捕获以下续行?(同样,不知道awk使这很难理解,感谢您的帮助)。在回答中添加了解释。“p:如果p==1,那么打印行”的最终见解让我能够理解。谢谢很好的解决方案!是的,这在linux上有效,谢谢!(不在Mac上,但它似乎没有使用GNU sed,正如您所指出的;
sed:1:“/^XXX/{:a;n;/^/ba};d”:意外的EOF(挂起的})
)。
sed -n '/^XXX/{:a;p;n;/^ /ba}' file
sed '/^XXX/{:a;n;/^\s/ba};d' file