循环AWK关联数组

时间:2014-01-24 22:03:50

标签: arrays loops awk associative

我在一个文件中使用一列来查找另一个文件中的值。第二个文件非常大,我想用awk在一次传递中找到所有值。我试过用关联数组做这个,但是我很难理解如何得到我想要的输出。我想拿F1,用$ 2来查找F2中的值,然后得到我在下面显示的输出,从F1开始是$ 0作为标题,然后从F2排序10美元并计算每个唯一字符串(即通过排序| uniq -c)。

F1

+ID=dnaK.p01 12121 TTGGGCAGTTGAAACCAGACGTTTCGCCCCTATTACAGAC[T]CACAACCACATGATGACCG

F2

solid309_20110930_FRAG_BC_bcSample12273_1541_657_F3     0       NC_012759       12121   42      35M     *       0       0       ACACAACCACATGATGACCGAATATATAGTGGCTC     BBBBBBA@BBBAB@?B@BBBB<5BBBAA@:>>&B7
solid309_20110930_FRAG_BC_bcSample12295_323_1714_F3     0       NC_012759       12121   42      35M     *       0       0       ACACAACCACATGATGACCGAATATATAGTGGAGA     BB@@A@@A@@@?@<=?@@=><6*7=?9993>4&7,
solid309_20110930_FRAG_BC_bcSample12325_1148_609_F3     0       NC_012759       12121   42      35M     *       0       0       ACACAACCACATGATGACCGAATATATAGTGGAGA     BBBB@B@?@B@@A@??BBBA@<.<==:6:1>9(<-
solid309_20110930_FRAG_BC_bcSample11796_1531_1170_F3    0       NC_012759       12122   42      35M     *       0       0       CACAACCACATGATGACCGAATATATAGTGGAGCA     '&&+&&)&')&0(.,',(.3+&&&+,&&&&&&&&&
solid309_20110930_FRAG_BC_bcSample12110_1166_1149_F3    0       NC_012759       12122   42      35M     *       0       0       CACAACCACATGATGACCGAATATATAGTGGAGAC     -(:18)538;,9277*'8:<)&,0-+)//3&'1+'
solid309_20110930_FRAG_BC_bcSample183_686_962_F3        0       NC_012759       12123   42      35M     *       0       0       ACAACCACATGATGACCGAATATATAGTGGAGTGC     BB?BBBB;BBBBBB@ABB;@7AA@@A@*>?+B8@9

我使用以下脚本

执行此操作
for line in `awk '{if ($1~"-") print ($2-34);else print $2}' $1`
do
awk -v l=$line '{if ($1~"-") l=l+34;if ($2==l) print }' $1 >> f2
awk -v l=$line '{if ($4==l) print $10}' URA2.sam | sort | uniq -c |awk '{if ($1>15) print}'>> f2
done

对于每一行,需要使用awk进行多次传递。我想我可以使用由F1制作的关联数组来完成一次传递。 F2按4美元排序。我使用以下脚本来尝试获得我想要的输出。

awk 'FNR==NR{a[$2]=$0;next}$4 in a{print $10}' f1 f2 | sort | uniq -c

2 个答案:

答案 0 :(得分:4)

以下是asorti()delete array使用GNU awk的输出:

$ cat tst.awk
function prtCounts(     val,sorted,idx) {
    if (prev in f1) {
        print f1[prev]
        asorti(count,sorted)
        for (idx=1; idx in sorted; idx++) {
            val = sorted[idx]
            print count[val], val
        }
    }
    delete count
}

NR==FNR { f1[$2] = $0; next }

{
    if ( (FNR>1) && ($4!=prev) )
        prtCounts()
    count[$10]++
    prev = $4
}

END { prtCounts() }

$ gawk -f tst.awk file1 file2
a 1 b c d
1 BALH
2 BLAH
b 2 b c d
1 HAHA
2 ZAHA

答案 1 :(得分:1)

我首先处理F1并使用关联数组保存,第二个字段作为键,整行作为值。然后,您只需要处理F2一次,每次第四个字段更改时,在第十个字段中打印重复值的数量,如:

awk '
    ## Process F1.
    FNR == NR {
        f1[$2] = $0
        next
    }

    ## Process F2.
    {
        if (FNR == 1 || prev_key == $4) {
            f2[$10]++
        }
        else {
            printf "%s\n", f1[prev_key]
            for (key in f2) {
                printf "%d %s\n", f2[key], key
            }
            delete f2
            f2[$10]++
        }
        prev_key = $4
    }

    END {
        printf "%s\n", f1[prev_key]
        for (key in f2) {
            printf "%d %s\n", f2[key], key
        }
    }
' F1 F2

它产生:

a 1 b c d
1 BALH
2 BLAH
b 2 b c d
2 ZAHA
1 HAHA