你如何用awk“规范化”记录列表

时间:2014-04-16 15:09:40

标签: awk

假设我有一个制表符分隔的记录列表,每个记录有两个字段,比如

bobby joe, jr   a,b,c
sue smith       b,d

想象一下,名称列和列之间有一个TAB字符,其中包含一系列单个字母。

目标是"规范化"数据看起来像这样:

bobby joe, jr   a
bobby joe, jr   b
bobby joe, jr   c
sue smith       b
sue smith       d

我想了解如何使用awk专门执行此操作。

2 个答案:

答案 0 :(得分:0)

您可以使用define spaces*comma作为可能的分隔符,然后循环打印第一个字段和另一个字段的字符串,就像这样:

$ awk -F" *|," '{for (i=2; i<=NF; i++) print $1, $i}' file
bob a
bob b
bob c
sue b
sue d

鉴于已更新的问题,使用data TAB records,您可以将records拆分为:

$ awk -F"\t" '{n=split($2,a,","); for (i=1;i<=n;i++) print $1, a[i]}' file
bobby joe, jr a
bobby joe, jr b
bobby joe, jr c
sue smith b
sue smith d

解释

  • -F"\t"将标签设置为字段分隔符。
  • n=split($2,a,",")在给定,分隔符的情况下将第二个字段切成片。当split()返回件数时,我们会将该数字存储在n
  • for (i=1;i<=n;i++) print $1, a[i]遍历各个部分,并将它们与第一个字段一起打印出来。

答案 1 :(得分:0)

如果你想要漂亮的印刷和整个shebang:

$ echo  -e "bobby joe, jr\ta,b,c\nsue smith\tb,d" \
    | awk -F"\t" '
BEGIN {MaxLen = 0} 
{
    a[NR] = $0; 
    if (length($1) > MaxLength) { 
        MaxLength = length($1)
    }
} 
END { 
    for (i in a) { 
        split(a[i], Fields); 
        split(Fields[2], Values, ","); 
        for (j = 1; j <= length(Values); j++) {
            printf("%-"MaxLength"s\t%s\n", Fields[1], Values[j])
        }
    }
}'
bobby joe, jr   a
bobby joe, jr   b
bobby joe, jr   c
sue smith       b
sue smith       d