Awk 如何使用sed提取特定段落并去除重复段落

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”

我想从下面显示的日志文件中选取以'-----------read----------'开头,以'finish'结尾的行,同时,去掉重复的段落(只保留相同段落的最后一个匹配)

在日志文件中,段落有固定的开始行和结束行,但没有固定的中间行,因此我使用
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