将第 1 列下的块中的多行列分组为 linux 中的 header

Group multiline columns in a block under column 1 as a header in linux

正在处理日志文件列并希望执行以下操作:

输入:

04.04.2018 11:52:44.014 123abc
04.04.2018 11:52:44.014 abc123
04.04.2018 11:52:44.014 xyz

04.04.2018 11:52:46.023 456abc
04.04.2018 11:52:46.023 dddfff
04.04.2018 11:52:46.023 zzz111
04.04.2018 11:52:46.023 d

期望的输出:

04.04.2018 11:52:44.014 123abcabc123xyz
04.04.2018 11:52:46.023 456abcdddfffzzz111d

到目前为止我已经尝试过 awk:

awk 'BEGIN{RS=ORS="\n";message="";time=}{message+=} END {print time; print message}'

使用上面的 awk 我想通过空行分隔符识别一个块,然后从第 1 行第 1 列和第 2 行获取日期和时间,然后为第 3 列的块中的每一行连接一条消息。最后打印时间和最后的消息。但是它并没有像我想的那样..

以下 awk 可能会对您有所帮助。

awk 'NF{a[,]=a[,]?a[,] $NF:$NF} END{for(i in a){print i,a[i]}}' SUBSEP=" "   Input_file

编辑: 如果我们需要按照 Input_file 的相同顺序输出,那么以下内容可能会对您有所帮助.

awk '!b[,]++ && NF{c[++i]= FS } NF{a[,]=a[,]?a[,] $NF:$NF} END{for(j=1;j<=i;j++){print c[j],a[c[j]]}}' SUBSEP=" "  Input_file

分组块而不检查 date/time 字段

$ awk '!NF {print line; line=""; next} 
           {line=(line?line $NF:[=10=])} 
       END {print line}' file 

04.04.2018 11:52:44.014 123abcabc123xyz
04.04.2018 11:52:46.023 456abcdddfffzzz111d

52 字符单节 mawk 解决方案(打高尔夫球时,不显示打高尔夫球):

awk 'NF { if (!seen[]++) printf "\n%s %s ", , ; printf  }' file

在 non-empty 行(其中 NF,字段数,非零):如果我们之前没有看到 date/time,打印一个换行符、日期、时间和一个space。然后总是打印第三列。

这不需要条目之间的空白 space 来合并它们。我更喜欢 mawk for portability (the ternary operator ?: used in other answers here is unique to gawk).


评论要求截断毫秒的版本。这是一个解决方案(注意输出也改变了;请参阅我的评论以了解如何保留第一个冲突时间的毫秒数):

awk 'NF { key=" " substr(,1,8); if (!seen[key]++) printf "\n%s ", key; printf  }' file