Awk 如何使用sed提取特定段落并去除重复段落
我想从下面显示的日志文件中选取以'-----------read----------'开头,以'finish'结尾的行,同时,去掉重复的段落(只保留相同段落的最后一个匹配) 在日志文件中,段落有固定的开始行和结束行,但没有固定的中间行,因此我使用Awk 如何使用sed提取特定段落并去除重复段落,awk,sed,paragraphs,Awk,Sed,Paragraphs,我想从下面显示的日志文件中选取以'-----------read----------'开头,以'finish'结尾的行,同时,去掉重复的段落(只保留相同段落的最后一个匹配) 在日志文件中,段落有固定的开始行和结束行,但没有固定的中间行,因此我使用 sed-n-e/------------read------/,/finish./p“$input\u file\u name 拾取段落,但不能删除重复的段落(某些段落可能重复) 我尝试过使用sed-n“0、/----read-/、/finish/p”
sed-n-e/------------read------/,/finish./p“$input\u file\u name
拾取段落,但不能删除重复的段落(某些段落可能重复)
我尝试过使用sed-n“0、/----read-/、/finish/p”
或sed-n/----read-/、/finish/、{p;q;}”
,但它们不起作用
他的理想产出是:
-------------read-----------
File reading...
2 failed
finish.
-------------read-----------
File reading...
1 failed
finish.
我该怎么做?如果有人能帮忙,我会非常感激的 使用类似的逻辑
$ cat tst.awk
{ gsub(/^[[:space:]]+|[[:space:]]+$/,"") }
!NF { next }
/-------------read-----------/ { inBlock=1; block="" }
inBlock { block = block $0 RS }
/finish/ {
if (NR==FNR) {
lastSeen[block] = FNR
}
else {
if (FNR==lastSeen[block]) {
printf "%s", block
}
}
inBlock=0
}
$ awk -f tst.awk file file
-------------read-----------
File reading...
2 failed
finish.
-------------read-----------
File reading...
1 failed
finish.
$ awk '/-+read-+/{k=$0; next}
k&&NF{sub(/ *$/,""); k=k RS $0}
/finish/{if(NR==FNR) a[k]++;
else if(!--a[k]) print k;
k=""}' log{,}
-------------read-----------
File reading...
2 failed
finish.
-------------read-----------
File reading...
1 failed
finish.
保留最后一条匹配记录会增加复杂性。我不确定我们应该在哪里查找我们不想重复的重复(例如,您的示例输入似乎没有文件名),但您可以通过一个简单的切换删除不必要的数据:
$ awk '/^-+read-+/ {show=1} show; $1=="finish." {show=0}' inputfile
这可能适用于您(GNU-sed):
这将过滤后的行存储在保留空间中,然后使用模式匹配和反向引用删除重复的段落。然而,这是一个脆弱的解决方案,因为它要求重复的段落是精确的副本(与给出的示例不同)。如果日志文件的结构完全如图所示(唯一有趣的一行是word
failed
),您可以使用sed-n-e/--------------read-----------/,/finish。/p“$input_file_name | grep'failed'| sort-u|awk'{printf'--------------read-------------\n文件读取…\n%s\n完成。\n“,$0}'
以获得所需的输出。sed
可以进行选择,但不能消除重复项awk
可以进行选择和重复消除;在使用sed
进行预处理后,它可以仅用于消除重复。你付你的钱,选择你的。我假设示例数据中的1
和2
在您读取的数据中确实是更长的文件名,对吗?嗨,安德烈,谢谢您的及时回复!我明白你的想法,但不幸的是,在我的真实日志文件中,它比示例更复杂,很抱歉,我没有清楚地描述它。在我的日志文件中,目标段落有固定的起始行和结束行,但中间行是意外的。但是段落,它们可能会在日志中重复,这就是为什么我想去掉它们。sed只用于在单独的行上进行简单的替换,仅此而已。这个问题并非如此,因此sed将是错误的工具。Awk是这项工作的合适工具。我没有看到重复的证据。是否有从示例输入数据中删除的文件名?或者“重复”仅由显示的故障数指定?第一个正则表达式中的冗余范围<代码>-+与[-]+
相同。
$ awk '/^-+read-+/ {show=1} show; $1=="finish." {show=0}' inputfile
sed -r '/-+read/,/finish\./H;$!d;x;:a;s/(\n-+read.*finish\.)(.*\1)/\2/;ta;s/.//' file