如何将表列转换为行?

如何将表列转换为行?

我有一个制表符分隔的 ( \t) 文件,其中包含两列:

a_1  T_b
a_2  T_c
a_2  T_d
a_2  T_e
a_3  T_f
a_4  B_a
a_4  B_b

我现在想将其转换为每行一个样本的文件,每个样本的所有值作为同一行上以空格分隔的第三个字段,如下所示:

a_1  T_b
a_2  T_c T_d T_e
a_3  T_f 
a_4  B_a B_b

我刚刚掌握了awk从第二个文件到第一个文件的转换。那么你能给我一些建议吗,请原谅我糟糕的unix技能。多谢。

答案1

使用 GNUdatamash按第一个制表符分隔的列进行分组并折叠另一列:

$ datamash groupby 1 collapse 2 <file
a_1     T_b
a_2     T_c,T_d,T_e
a_3     T_f
a_4     B_a,B_b

这假设文件按第一个字段排序。如果不是,则使用datamash-s( --sort) 选项,或将数据通过管道传输到datamashviasort

如果您希望第二个字段的“子字段”由空格而不是逗号分隔,请使用以下命令将逗号替换为空格awk

$ datamash groupby 1 collapse 2 <file | awk -F '\t' 'BEGIN { OFS=FS } { gsub(","," ",$2) }; 1'
a_1     T_b
a_2     T_c T_d T_e
a_3     T_f
a_4     B_a B_b

答案2

这是一种方法:

$ awk -F'\t' '
      { 
        $1 in a? a[$1]=a[$1]" "$2 : a[$1]=$2 
      }
      END{ 
        for(i in a){print i"\t"a[i]} 
      }' file

a_1 T_b
a_2 T_c T_d T_e
a_3 T_f
a_4 B_a B_b

这里的想法是,我们创建一个关联数组,a其键是第一个字段,即样本名称。然后,对于每一行,如果该样本已作为键存在,我们将其值设置为该行的第二个字段,如果不是,我们将当前的第二个字段附加到现有值。同样的事情可以写得更详细,如下所示:

$ awk -F'\t' '
      { 
        if($1 in a){ a[$1]=a[$1]" "$2 }
        else       { a[$1]=$2 }
      }
      END{ 
        for(i in a){print i"\t"a[i]} 
      }' file

答案3

使用 Raku(以前称为 Perl_6)

raku -e 'my %hash; for lines>>.words() {%hash.append( .[0] => .[1] )}; .say for %hash.sort;' 

或者

raku -e 'my %hash; for lines.map(*.words) -> ($k,$v) {%hash.append: $k => $v }; .say for %hash.sort;' 

简而言之,Raku 中内置的哈希功能用于解决这个问题。行被读取并分成 (空格分隔) words。单词被附加到 hash 中%hash,第一列成为键,第二列成为值。 Raku 的=>“胖箭头”运算符用于构造键值对,并且append例程根据键累加值(哈希不能有重复的键)。

输入示例:

a_1  T_b
a_2  T_c
a_2  T_d
a_2  T_e
a_3  T_f
a_4  B_a
a_4  B_b

示例输出:

a_1 => T_b
a_2 => [T_c T_d T_e]
a_3 => T_f
a_4 => [B_a B_b]

.say将上面的代码更改为.put获取\t制表符分隔的输出。或者定义您自己的字段分隔符:下面的示例中,第一列与第二列用 4 个空格分隔,value第二列用逗号分隔(如果需要,请更改为空格):

~$ raku -e 'my %hash; for lines.map(*.words) -> ($k,$v) {%hash.append: $k => $v }; for %hash.sort {put .key, "    ", .value.join(",")};'
a_1    T_b
a_2    T_c,T_d,T_e
a_3    T_f
a_4    B_a,B_b

https://docs.raku.org/language/hashmap#Mutable_hashes_and_immutable_maps
https://docs.raku.org/routine/=%3E
https://raku.org

相关内容