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

时间:2018-04-05 15:33:44

标签: linux awk sed tr

使用日志文件列并希望执行以下操作:

输入:

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=$1}{message+=$3} END {print time; print message}'

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

3 个答案:

答案 0 :(得分:2)

关注awk可能对您有帮助。

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

编辑: 如果我们需要输出与Input_file相同的顺序,那么以下内容可以帮助您。

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

答案 1 :(得分:2)

在不检查日期/时间字段的情况下对块进行分组

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

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

答案 2 :(得分:1)

52个单节的maank makk解决方案(打高尔夫球时,没有显示高尔夫球):

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

在非空行(其中NF,字段数为非零)上:如果我们还没有看到之前的日期/时间,则打印换行符,日期,时间和空格。然后始终打印第三列。

这不需要条目之间的空白空间来合并它们。我更喜欢mawk for portability(此处其他答案中使用的ternary operator ?:对于gawk来说是唯一的。)

注释请求了一个版本,它会截断毫秒数。这是一个做到这一点的解决方案(请注意,输出也会改变;请参阅我的评论,了解如何保留第一个冲突时间&#39;毫秒):

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