3

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

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 命令来一次生成一行,给定一个组 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

4 回答 4

3

我不太了解 awk,但您可以使用 bash、排序、grep、剪切和粘贴来完成此操作:

#!/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

不确定输出分隔符是否必须" | "或是否"|"会这样做。

于 2013-09-18T19:03:11.007 回答
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
于 2013-09-18T18:50:38.890 回答
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
于 2013-09-18T20:34:02.700 回答
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
于 2013-09-18T20:22:53.213 回答