Awk:停止'print'添加换行符以及如何循环/自动化

时间:2013-09-18 18:42:28

标签: bash awk

就目前而言,我有这样的制表符分隔数据(为清楚起见,这里添加了标题):

EntryID    GroupID    Result
039848     00100      Description 1  
088345     00200      Description 2
748572     00435      Description 3
884938     00200      Description 2
000392     00200      Description 3
008429     00100      Description 4

我要做的是将数据压缩成组。我希望输出一个表,其中列A是groupID(没有重复),列B是与该组关联的所有描述的组合。输出示例如下:

00100      Description 1 | Description 4
00200      Description 2 | Description 2| Description 3
00435      Description 3

我尝试编写一个awk命令,一次生成一行,给定一个Group ID作为参数:

$ awk -F '\t' '/00100/ { print $2 '\t' $3 }' table.txt > output.txt

这样可行,但每次点击都会打印在换行符上,例如

00100    Description 1
00100    Description 2

etc

我认为这可以通过将ORS指定给替代字符,或者使用printf而不是print来解决,但是当我尝试其中任何一个时

$ awk -F '\t' 'BEGIN {ORS = '\t'} /00100/ { print $2 '\t' $3 }' table.txt > output.txt
or
$ awk -F '\t' '/00100/ { printf $2 '\t' $3 }' table.txt > output.txt

输出中实际上没有任何变化。

一旦我解决了问题,我遇到的另一个问题是我有成千上万的小组要重复这个问题。我有一个列表,列出了数据中存在的每个组ID,存储在一个不同的文件中,我想自动为每个ID提供awk。

我已经尝试修改一个我以前用过以类似的方式将ID提供给grep的命令,但我也没有任何运气,因为它只是挂起:

$ for i in `$ cat groupIDs.txt`; do awk -F '\t' '/$i/ { print $2 '\t' $3 }' table.txt' >> test_results.txt ; done;

我是如何解决这些问题的?

4 个答案:

答案 0 :(得分:3)

我对awk并不多,但你可以用bash,sort,grep,cut和paste来做到这一点:

#!/bin/bash

groups=$(cut -f2 "$1" | sort -u)
for group in $groups ; do
    echo -n "$group "
    cut -f2- "$1" | grep "^$group" | cut -f2 | paste -d"|" -s -
done

这会产生以下输出:

00100   Description 1|Description 4
00200   Description 2|Description 2|Description 3
00435   Description 3

不确定输出分隔符是否" | "还是"|"

答案 1 :(得分:2)

你可以尝试这个awk命令:

$ awk '{i=$2;$1=""; $2="";a[i]=a[i]?a[i]" |"$0:$0}END{for (i in a) print i, a[i]} ' file
00435   Description 3
00100   Description 1 |  Description 4
00200   Description 2 |  Description 2 |  Description 3

或者由于文件是制表符分隔的,您可以将其简化为

$  awk -F'\t' '{a[$2]=a[$2]?a[$2]" | "$3:$3}END{for (i in a) print i"\t"a[i]} ' file
00435   Description 3
00100   Description 1 | Description 4
00200   Description 2 | Description 2 | Description 3

答案 2 :(得分:0)

$ cat tst.awk
BEGIN {
    FS=OFS="\t"
    split(tgtS,tmpA,/,/)
    for (i in tmpA)
        tgtA[tmpA[i]]
}

(!tgtS) || ($2 in tgtA) {
    descs[$2] = descs[$2] sep[$2] $3
    sep[$2]=" | "
}

END {
    for (gid in descs)
        print gid, descs[gid]
}
$ 
$ gawk -f tst.awk file
00435   Description 3
00100   Description 1 | Description 4
00200   Description 2 | Description 2 | Description 3
$ 
$ gawk -v tgtS="00100" -f tst.awk file
00100   Description 1 | Description 4
$ 
$ gawk -v tgtS="00100,00200" -f tst.awk file
00100   Description 1 | Description 4
00200   Description 2 | Description 2 | Description 3

答案 3 :(得分:0)

代码:

#!/usr/bin/awk -f

BEGIN {
    FS = OFS = "\t"
    getline
}
{
    if ($2 in a) {
        a[$2] = a[$2] " | " $3
    } else {
        a[$2] = $3
        b[i++] = $2
    }
}
END {
    for (j = 0; j < i; ++j) {
        k = b[j]
        print k, a[k]
    }
}

输入:

EntryID GroupID Result
039848  00100   Description 1
088345  00200   Description 2
748572  00435   Description 3
884938  00200   Description 2
000392  00200   Description 3
008429  00100   Description 4

输出:

00100   Description 1 | Description 4
00200   Description 2 | Description 2 | Description 3
00435   Description 3