bash - 重新排列文件中的数据(不是直接转置)

标签 bash shell awk sed gawk

我有一个这样的文件(超过 2.5k 行):

NAME YEAR A B C
JOHN Y1 10,00 19,00 65,00
JOHN Y2 11,00 23,00 64,00
JOHN Y3 12,00 33,00 34,00
JOHN Y4 13,00 34,00 32,00
PAUL Y1 14,00 43,00 23,00
PAUL Y2 15,00 90,00 34,00
PAUL Y3 16,00 32,00 56,00
PAUL Y4 20,00 45,00 65,00
RINGO Y1 25,00 60,00 87,00
RINGO Y2 24,00 30,00 23,00
RINGO Y3 31,00 20,00 54,00
RINGO Y4 75,00 10,00 12,00

如您所见,每个名称重复 4 次(4 行)以“存储”4 年的值,并且每年有 3 个值(A、B 和 C)。

我需要重新排列数据,以便每个名称都显示在一行中。因此,原来以行显示的 4 年必须以新列显示,如下所示:

NAME A/Y1 A/Y2 A/Y3 A/Y4 B/Y1 B/Y2 B/Y3 B/Y4 C/Y1 C/Y2 C/Y3 C/Y4
JOHN 10,00 11,00 12,00 13,00 19,00 23,00 33,00 34,00 65,00 64,00 34,00 32,00
PAUL 14,00 15,00 16,00 20,00 43,00 90,00 32,00 45,00 23,00 34,00 56,00 65,00
RINGO 25,00 24,00 31,00 75,00 60,00 30,00 20,00 10,00 87,00 23,00 54,00 12,00

此外,可接受的输出格式可以是:

NAME Y1/A Y1/B Y1/C Y2/A Y2/B Y2/C Y3/A Y3/B Y3/C Y4/A Y4/B Y4/C

我不确定哪一个会“更容易”实现,但是两种输出格式都可以。

据我所知,这不是“直接转置”,我也没有发现任何类似的问题,所以我再次提出了更详细的问题。

最佳答案

将 GNU awk 用于真正的多维数组:

$ cat tst.awk
NR==1 { split($0,hdr); next }
{
    idx = (NR-2)%4+1
    val[idx][0]
    split($0,val[idx])
}
NR==5 {
    printf "%s", hdr[1]
    for (j=3; j in hdr; j++) {
        for (i=1; i<=idx; i++) {
            printf "%s%s", OFS, hdr[j]"/"val[i][2]
        }
    }
    print ""
}
idx==4 {
    printf "%s", $1
    for (j=3; j<=NF; j++) {
        for (i=1; i<=idx; i++) {
            printf "%s%s", OFS, val[i][j]
        }
    }
    print ""
}

$ awk -f tst.awk file
NAME A/Y1 A/Y2 A/Y3 A/Y4 B/Y1 B/Y2 B/Y3 B/Y4 C/Y1 C/Y2 C/Y3 C/Y4
JOHN 10,00 11,00 12,00 13,00 19,00 23,00 33,00 34,00 65,00 64,00 34,00 32,00
PAUL 14,00 15,00 16,00 20,00 43,00 90,00 32,00 45,00 23,00 34,00 56,00 65,00
RINGO 25,00 24,00 31,00 75,00 60,00 30,00 20,00 10,00 87,00 23,00 54,00 12,00

关于bash - 重新排列文件中的数据(不是直接转置),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39617699/

相关文章:

linux - bash 的目录书签

linux - 在不重启 Ubuntu 的情况下全局设置环境变量

mongodb - 如何克隆(重复)同一数据库集合中的 MongoDB 对象?

r - sub 和 gsub 函数?

bash - 使用 bash 脚本将文本文件一分为二

awk 语句 - 如果没有找到 (grep'ed) 做

Bash 文件批量替换

bash - 在 Docker 中设置环境变量

bash - 如何在没有交互式编辑器的情况下自动使用 Bash 创建一个 cron 作业?

Linux 命令中的命令