Sed awk |基于字段匹配的合并线

Sed awk |基于字段匹配的合并线,sed,awk,Sed,Awk,我需要以下方面的帮助: 输入文件: abc message=sent session:111,x,y,z pqr message=receive session:111,4,5,7 abc message=sent session:123,x,y,z pqr message=receive session:123,4,5,7 abc message=sent session:342,x,y,z abc message=sent session:589,x,y,z pqr message=rece

我需要以下方面的帮助:

输入文件:

abc message=sent session:111,x,y,z
pqr message=receive session:111,4,5,7
abc message=sent session:123,x,y,z
pqr message=receive session:123,4,5,7
abc message=sent session:342,x,y,z
abc message=sent session:589,x,y,z
pqr message=receive session:589,4,5,7
输出文件:

abc message=sent session:111,x,y,z, pqr message=receive session:111,4,5,7
abc message=sent session:123,x,y,z, pqr message=receive session:123,4,5,7
abc message=sent session:342,x,y,z, NOMATCH
abc message=sent session:589,x,y,z, pqr message=receive session:589,4,5,7
注:

如果您在源文件中看到,对于每个“已发送”消息,都有“接收”
仅对于会话=342,没有接收
会话未知,无法硬编码

因此,只合并那些发送和接收的会话号匹配的会话号

这里有一种使用
awk
的方法。运行方式如下:

awk -f script.awk file
script.awk的内容

{
    x = $0

    gsub(/[^:]*:|,.*/,"")

    a[$0] = (a[$0] ? a[$0] "," FS : "") x
    b[$0]++
}

END {
    for (i in a) {
        print (b[i] == 2 ? a[i] : a[i] "," FS "NOMATCH") | "sort"
    }
}
结果:

abc message=sent session:111,x,y,z, pqr message=receive session:111,4,5,7
abc message=sent session:123,x,y,z, pqr message=receive session:123,4,5,7
abc message=sent session:342,x,y,z, NOMATCH
abc message=sent session:589,x,y,z, pqr message=receive session:589,4,5,7
abc message=sent session:111,x,y,z pqr message=receive session:111,4,5,7
abc message=sent session:123,x,y,z pqr message=receive session:123,4,5,7
abc message=sent session:589,x,y,z pqr message=receive session:589,4,5,7
abc message=sent session:342,x,y,z NO MATCH
或者,这里有一个班轮:

awk '{ x = $0; gsub(/[^:]*:|,.*/,""); a[$0] = (a[$0] ? a[$0] "," FS : "") x; b[$0]++ } END { for (i in a) print (b[i] == 2 ? a[i] : a[i] "," FS "NOMATCH") | "sort" }' file
请注意,如果不关心已排序的输出,则可以将管道放置到
sort
。HTH.

另一种方式:

awk -F "[:,]"  '/=sent/{a[$2]=$0;}/=receive/{print a[$2], $0;delete a[$2];}END{for(i in a)print a[i],"NO MATCH";}' file
结果:

abc message=sent session:111,x,y,z, pqr message=receive session:111,4,5,7
abc message=sent session:123,x,y,z, pqr message=receive session:123,4,5,7
abc message=sent session:342,x,y,z, NOMATCH
abc message=sent session:589,x,y,z, pqr message=receive session:589,4,5,7
abc message=sent session:111,x,y,z pqr message=receive session:111,4,5,7
abc message=sent session:123,x,y,z pqr message=receive session:123,4,5,7
abc message=sent session:589,x,y,z pqr message=receive session:589,4,5,7
abc message=sent session:342,x,y,z NO MATCH

当遇到
send
记录时,它将以会话id作为索引存储在数组中。当遇到
receive
记录时,将从数组中提取
send
记录,并与
receive
记录一起打印。此外,当接收到
receive
记录时,发送的记录将从阵列中删除。最后,数组中的所有剩余记录都被打印为不匹配。

消息=接收是否总是跟在消息=立即发送之后,如本例所示?不总是。。如果同一个会话中有“message=sent”和“message=receive”,则只有组合。因此,如果您看到,则示例中有2个message=sent(一个接一个),这意味着我需要跳过一个sent并继续下一行您必须awk和sed吗?在perl中这样做很容易。有了awk和sed,它可能会变得难看。如果不耗费时间,perl也很好。为此,我们做了很多工作。。但我无法理解其中的逻辑。。请你再解释一遍,大师。。我还有一个问题。。是否可以按顺序按顺序打印输出?例如,在会话123之后,不应在两行之间打印匹配项。如果我要重新打印,则应如下所示:对于每一个“=发送”,仅在下一行中搜索“=接收”,搜索相同的会话号
,因此仅合并具有匹配会话号的发送和接收项,否则按顺序打印发送项
Hello Steve。。你能解释一下逻辑吗?为什么我们要把排序放在最后?