“你怎么看?”;“正常化”;带有awk的记录列表

“你怎么看?”;“正常化”;带有awk的记录列表,awk,Awk,假设我有一个以制表符分隔的记录列表,每个记录有两个字段,如下所示 bobby joe, jr a,b,c sue smith b,d 假设名称列和包含一系列单个字母的列之间有一个制表符 目标是“规范化”数据,使其看起来像这样: bobby joe, jr a bobby joe, jr b bobby joe, jr c sue smith b sue smith d $ awk -F" *|," '{for (i=2; i<=NF;

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

bobby joe, jr   a,b,c
sue smith       b,d
假设名称列和包含一系列单个字母的列之间有一个制表符

目标是“规范化”数据,使其看起来像这样:

bobby joe, jr   a
bobby joe, jr   b
bobby joe, jr   c
sue smith       b
sue smith       d
$ awk -F" *|," '{for (i=2; i<=NF; i++) print $1, $i}' file
bob a
bob b
bob c
sue b
sue d
$ 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

我想学习如何特别使用
awk

来实现这一点。您可以使用define
空格*
逗号
作为可能的分隔符,然后循环字符串打印第一个字段和另一个字段,如下所示:

bobby joe, jr   a
bobby joe, jr   b
bobby joe, jr   c
sue smith       b
sue smith       d
$ awk -F" *|," '{for (i=2; i<=NF; i++) print $1, $i}' file
bob a
bob b
bob c
sue b
sue d
$ 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如果您想要漂亮的打印和整个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
    
    $echo-e“小鲍比·乔\ta,b,c\nsue smith\tb,d”\
    |awk-F“\t”
    开始{MaxLen=0}
    {
    a[NR]=$0;
    如果(长度($1)>最大长度){
    MaxLength=长度($1)
    }
    } 
    结束{
    对于(a中的i){
    拆分(a[i],字段);
    拆分(字段[2],值“,”);
    
    对于(j=1;j,但是如果我有制表符分隔的字段,而第二个字段(未显示,但在第一个和第三个字段之间)可能包含空格或逗号,该怎么办?那么您最好更新您的问题,显示一些这样的示例输入。@dan只需将
    -F*|,“
    更改为
    -F”\t|,”
    @veryhungrymike请查看最新版本的question@dan刚刚编辑以回答此
    数据
    选项卡
    记录
    新输入文件。分隔符是一个制表符。名称字段中没有制表符,或字段中没有逗号分隔的字母。请注意,如果您仅循环
    以获取(i in values)
    。有关更多参考信息,请参阅。感谢您的回答。但我必须将其交给@fedorqui,因为他首先发布并处理了我的编辑。@fedorqui我知道。OP没有指定顺序是重要的。我只需使用
    PROCINFO[“sorted_in”]
    就可以了,但有些人的gawk版本并不流行。