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