根据不同的列值将多列合并为行

时间:2019-09-25 12:03:25

标签: linux awk

我有一个带注释的数据集(制表符分隔),并希望创建一个按GeneName排序的新文件。由于所有的NonGene在文件中都具有相同的名称,因此我很难找到一种对它们进行排序以获得所需输出的方法。

我的文件示例:

GeneName    Pos SNP
NoneGene    1   22:1_A/T
NoneGene    2   22:2_A/G
NoneGene    3   22:3_A/C
Gene1       4   22:4_A/G
Gene1       5   22:5_G/T
NoneGene    6   22:6_T/C
NoneGene    7   22:7_A/G
NoneGene    8   22:8_T/G
Gene2       9   22:9_G/T
Gene2       10  22:10_C/T
NoneGene    11  22:11_T/G
Nonegene    12  22:12_A/C

所需的输出:

NoneGene    22:1_A/T    22:2_A/G    22:3_A/C
Gene1       22:4_A/G    22:5_G/T    
NoneGene    22:6_T/C    22:7_A/G    22:8_T/G
Gene2       22:9_G/T    22:10_C/T
Nonegene    22:11_T/G   22:12_A/C

所需输出数据中的每一行是一个基因/一组SNP(例如22:1_A / T),以制表符分隔。每行中的第一个元素是基因(例如,NoneGene,gene1,NoneGene,gene2等),其余部分用于以22:1_A / T格式编写的变体ID。每个基因有多少个SNP会有所不同。应该将SNP从最低值到最高值进行排序(例如22:1_A / T 22:2_A / G 22:3_A / C)。

我更喜欢awk(或gawk)解决方案,但是我对编码完全陌生,因此将不胜感激。

3 个答案:

答案 0 :(得分:0)

不是awk,但是总是方便使用的GNU datamash使操作变得简单:

$ tail -n +2 input.tsv | datamash -g 1 collapse 3  | tr ',' '\t'
NoneGene    22:1_A/T    22:2_A/G    22:3_A/C
Gene1   22:4_A/G    22:5_G/T
NoneGene    22:6_T/C    22:7_A/G    22:8_T/G
Gene2   22:9_G/T    22:10_C/T
NoneGene    22:11_T/G   22:12_A/C

这确实假设您的输入已经按基因进行了划分,并且已经按SNP值进行了进一步的排序,就像它们在样本数据中一样。

  • tail -n +2分隔标题行
  • 使用datamash将组变成看起来像NonGene 22:1_A/T,22:2_A/G,22:3_A/C的行
  • 使用tr将逗号转换为制表符以最终输出。

答案 1 :(得分:0)

如果您想使用awk,请尝试此操作,将定界符更改为-F“ \ t”

组合所有键:

 awk -F" " '{  
  if(NR>1) {
   if ( length(a[$1]) == 0 ) {
      a[$1]=$3 
   }else { 
      a[$1] = a[$1]"\t"$3 
   }
  }
} END{ 
   for (e in a) { 
     print e,a[e]
   } 
} ' test.txt

如果您希望将后续键分组,请尝试

 awk -F" " 'BEGIN{i=0; prev=""; }{ 
    if (NR>1) {
      if(prev==$1) { a[i]=a[i]"\t"$3; }
      else if(prev==$1 && length(a[i])>0) { a[i]=a[i]"\t"$3;   prev=$1;}
      else {i=i+1; a[i]=$1"\t"$3; prev=$1;}
    }
 }
END { for (e in a) print a[e]}
' test.txt

答案 2 :(得分:-1)

另一个awk

awk '$1!=f {printf "\n%s %s ",$1,$3;f=$1;next} {printf "%s ",$3}' file

NoneGene 22:1_A/T 22:2_A/G 22:3_A/C
Gene1 22:4_A/G 22:5_G/T
NoneGene 22:6_T/C 22:7_A/G 22:8_T/G
Gene2 22:9_G/T 22:10_C/T
NoneGene 22:11_T/G
Nonegene 22:12_A/C 

前面没有新行,而在末尾添加新行:

awk '$1!=f {printf (NR==1?"":"\n")"%s %s ",$1,$3;f=$1;next} {printf "%s ",$3} END {print ""}' file
NoneGene 22:1_A/T 22:2_A/G 22:3_A/C
Gene1 22:4_A/G 22:5_G/T
NoneGene 22:6_T/C 22:7_A/G 22:8_T/G
Gene2 22:9_G/T 22:10_C/T
NoneGene 22:11_T/G
Nonegene 22:12_A/C