首页 > 解决方案 > 如何在 unix 中转置或旋转文本文件的数据?

问题描述

我在 unix 中有一个包含此类数据的输入文本文件。

Event_date:20190512044638
Error_code:5858
Event_type:GPRS data
Duration:772
Missing_provider_id:46009

Event_date:20190512044638
Error_code:780678

Event_date:20190512064535
Error_code:5858
Event_type:GPRS data
Duration:2172
Missing_provider_id:722310

我希望这些数据采用这种输出格式:

Event_date      Error_code  Event_type  Duration  Missing_provider_id
20190512044638  5858        GPRS data   772       46009
20190512044638  780678      
20190512064535  5858        GPRS data   2172      722310

我尝试了 awk 和 sed 命令的组合,但没有成功。我怎样才能实现这个输出?

Event_date:20190512044638
Error_code:5858
Event_type:GPRS data
Duration:772
Missing_provider_id:46009

Event_date:20190512044638
Error_code:780678

Event_date:20190512064535
Error_code:5858
Event_type:GPRS data
Duration:2172
Missing_provider_id:722310

我希望这些数据采用这种输出格式:

Event_date      Error_code  Event_type  Duration  Missing_provider_id
20190512044638  5858        GPRS data   772       46009
20190512044638  780678      
20190512064535  5858        GPRS data   2172      722310

标签: linuxunixawkgreptranspose

解决方案


使用 GNU awk 和 2D 数组:

awk '
BEGIN {                         
    r=2                                           # data records in a start from 2
    FS=":"                                        # split at :
    OFS="\t"                                      # tab separated fields
    a[0][0]                                       # initialize a array
}
$0!="" {                                          # for nonempty records
    if(!($1 in a[0])) {                           # add keys to headers when needed
        a[0][$1]=++f                              # for lookups
        a[1][f]=$1                                # for printing
    }
    a[r][a[0][$1]]=$2                             # store value
    next
}
{                                                 # empty record -> new array record
    r++
}
END {                                             # after records are processed
    # delete a[0][0]                              # 
    for(i=1;i<=r;i++)                             # iterate records
        for(j=1;j<=f;j++)                         # iterate fields
            printf "%s%s",a[i][j],(j==f?ORS:OFS)  # output
}
' file | column -t -s $'\t'                       # column used for pretty-print

输出:

Event_date      Error_code  Event_type  Duration  Missing_provider_id
20190512044638  5858        GPRS data   772       46009
20190512044638  780678
20190512064535  5858        GPRS data   2172      722310

推荐阅读