由AWK组织文件

时间:2017-03-21 10:16:48

标签: bash file unix awk

好吧,我有以下文件:

week  ID      Father  Mother  Group  C_Id    Weight  Age  System  Gender
9     107001  728     7110    922    107001  1287    56   2       2
10    107001  728     7110    1022   107001  1319    63   2       2
11    107001  728     7110    1122   107001  1491    70   2       2
1     107002  702     7006    111    107002  43      1    1       1
2     107002  702     7006    211    107002  103     7    1       1
4     107002  702     7006    411    107002  372     21   1       1
1     107003  729     7112    111    107003  40      1    1       1
2     107003  729     7112    211    107003  90      7    1       1
5     107003  729     7112    511    107003  567     28   1       1
7     107003  729     7112    711    107003  1036    42   1       1

我需要转置Age($ 8)和Weight($ 7)列,其中列($ 8)将是新标签(1,7,21,28,42,56,63,70)。此外,年龄标签应按升序排列。但并非所有动物都采用所有年龄措施,不具备的动物应该给予" NS"符号。将维护Id,父,母,系统和性别列,但通过转换年龄和权重列,没有必要像第一个表中那样重复这些变量。不需要Week,Group和C_Id列。在视觉上,我需要这样的文件:

ID  Father  Mother  System  Gender   1  7   21  28  42   56   63   70
107001  728   7110     2        2    NS NS  NS  NS  NS   1287 1319 1491
107002  702   7006     1        1    43 103 372 NS  NS   NS   NS   NS
107003  729   7112     1        1    40 90  NS  567 1036 NS   NS   NS

我试过这个程序:

#!/bin/bash

awk 'NR==1{h=$2 OFS $3 OFS $4 OFS $9 OFS $10; next}
            {a[$2]=(($1 in a)?(a[$1] OFS $NF):(OFS $3 OFS $4 OFS $9 OFS $10));
             if(!($8 in b)) {h=h OFS $8; b[$8]}}
        END{print h; for(k in a) print k,a[k]}' banco.txt | column -t > a

但我明白了:

ID  Father  Mother  System  Gender
  56  63  70  1  7  21  28  42
107001  728   7110     2        2
107002  702   7006     1        1
107003  729   7112     1        1

我在那时陷入困境,有什么建议吗?感谢。

1 个答案:

答案 0 :(得分:1)

使用GNU awk for“sorted_in”:

$ cat tst.awk
{
    id = $2
    weight = $7
    age = $8

    idAge2weight[id,age] = weight
    id2common[id] = $2 OFS $3 OFS $4 OFS $9 OFS $10
    ages[age]
}
END {
    PROCINFO["sorted_in"] = "@ind_num_asc"
    printf "%s", id2common["ID"]
    for (age in ages) {
        printf "%s%s", OFS, age
    }
    print ""
    delete id2common["ID"]

    for (id in id2common) {
        printf "%s", id2common[id]
        for (age in ages) {
            weight = ((id,age) in idAge2weight ? idAge2weight[id,age] : "NS")
            printf "%s%s", OFS, weight
        }
        print ""
    }
}

$ awk -f tst.awk file | column -t
ID      Father  Mother  System  Gender  Age  1   7    21   28   42    56    63    70
107001  728     7110    2       2       NS   NS  NS   NS   NS   NS    1287  1319  1491
107002  702     7006    1       1       NS   43  103  372  NS   NS    NS    NS    NS
107003  729     7112    1       1       NS   40  90   NS   567  1036  NS    NS    NS

我将管道添加到column -t,以便您可以看到字段对齐。