如何基于AWK / UNIX中的公共字段将行中的分隔字段合并为一个

时间:2015-01-30 03:00:36

标签: linux unix awk scripting

我仍然只是UNIX的新用户,尤其是AWK。我有问题要根据前2列值合并行。我的原始数据来自以下文件:

Original data content
========================

ID1 ID2 Field1  Field2
1   1   11F1    11F2
1   2   12F1    12F2
2   1   21F1    21F2
2   2   22F1    22F2
ID1 ID2 Field3  Field4
1   1   11F3    11F4
1   2   12F3    12F4
2   1   21F3    21F4
2   2   22F3    22F4
ID1 ID2 Field5  Field6
1   1   11F5    11F6
1   2   12F5    12F6
2   1   21F5    21F6
2   2   22F5    22F6

正如您所注意到的,列被分成不同的行/块,但ID字段和列标题仍然可用并重复。所以我想要实现的目标如下:

ID1 ID2 Field1  Field2  Field3  Field4  Field5  Field6
1   1   11F1    11F2    11F3    11F4    11F5    11F6
1   2   12F1    12F2    12F3    12F4    12F5    12F6
2   1   21F1    21F2    21F3    21F4    21F5    21F6
2   2   22F1    22F2    22F3    22F4    22F5    22F6

将all合并为单个块/表。 但是不知道如何在AWK中做到这一点,或者是否可以用AWK实现。

非常感谢。 Htat Ko

2 个答案:

答案 0 :(得分:3)

是的,可以使用awk

awk ' 
{ key = $1 FS $2 }
!seen[key]++ { keys[++total] = key }
{ values[key] = ( key in values ? values[key] FS $3 FS $4 : $3 FS $4 ) }
END {
    for (cnt=1; cnt<=total; cnt++) 
    print keys[cnt], values[keys[cnt]]
}' file
  • 将第一列和第二列格式化为
  • 使用数组seen记住发生的顺序。
  • 测试您的密钥是否存在于数组中(我们在这里使用三元运算)。如果存在,请使用新数据集附加现有值。如果不存在,请将其作为值。
  • END块中,迭代并打印。
  • 如果您有多列,则将列存储在变量中,然后在存储之前从中删除键。

答案 1 :(得分:1)

你也可以在没有Awk的情况下做到这一点:

$ sort -n data | sed -e 's/  */ /g' | paste - - - -d' ' | cut -d' ' -f 1,2,3,4,7,8,11,12

<强>输出

ID1 ID2 Field1 Field2 Field3 Field4 Field5 Field6
1 1 11F1 11F2 11F3 11F4 11F5 11F6
1 2 12F1 12F2 12F3 12F4 12F5 12F6
2 1 21F1 21F2 21F3 21F4 21F5 21F6
2 2 22F1 22F2 22F3 22F4 22F5 22F6