AWK将第一列相同的行合并为特定格式

时间:2019-11-07 11:05:09

标签: awk merge conditional-statements

我想将相同$ 1的tab sep文件行(包含9列)合并为特定格式。

输入:

DIA   55tyr  10 HOM   1 olig_al  ....
ALOP  66tel  11 HET   3 alin_et  .... 
ALOP  128ryp 11 HET   3 ivi_es   ....
ALOP  131dat 11 HET   3 osi_et   ....
ANDY  12dou  13 WILD  4 sas_rar  ....
KOLIK 16dev  14 HET   6 levi_lol ... 

输出:

DIA   55tyr  10 HOM   1 olig_al  ....
ALOP  66tel_128ryp_131dat 11 HET_HET_HET 3 alin_et_ivi_es_osi_et ....
ANDY  12dou  13 WILD  4 sas_rar  ....
KOLIK 16dev  14 HET   6 levi_lol ...

A可以合并它,并以此一行一行地写一行:

awk -F'\t' -v OFS='\t' '{x=$1;$1="";a[x]=a[x]$0}END{for(x in a)print x,a[x]}'

,然后使用一些条件。是否可以编写awk代码以合并具有相同$ 1的行,并使用分隔符“ _”将$ 2,$ 4,$ 6,$ 7,$ 8,$ 9合并在一起,而$ 3和$ 5行将像输出一样是唯一的? 感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

第一个解决方案(将所有具有相同第一个字段的字段连接起来): 请您尝试以下操作。这将处理$ 1的顺序,其中将以相同的方式显示输出。同样,这将一直运行到最大字段数(整个Input_file)。

awk '
!a[$1]++{
  b[++count]=$1
}
{
  val=val>NF?val:NF
  for(i=2;i<=NF;i++){
    c[$1,i]=(c[$1,i]?c[$1,i] "_":"")$i
  }
}
END{
  for(i=1;i<=count;i++){
    printf("%s ",b[i])
    for(j=2;j<=val;j++){
      printf("%s %s",c[b[i],j]?c[b[i],j]:0,j==val?ORS:OFS)
    }
  }
}'  Input_file

输出如下。

DIA 55tyr  10  HOM  1  olig_al 
ALOP 66tel_128ryp_131dat  11_11_11  HET_HET_HET  3_3_3  alin_et_ivi_es_osi_et 
ANDY 12dou  13  WILD  4  sas_rar 
KOLIK 16dev  14  HET  6  levi_lol 


第二种解决方案(仅连接偶数字段):

awk '
!a[$1]++{
  b[++count]=$1
}
{
  val=val>NF?val:NF
  for(i=2;i<=NF;i++){
    if(i%2==0){
    c[$1,i]=(c[$1,i]?c[$1,i] "_":"")$i
    }
    else{
        c[$1,i]=$i
    }
  }
}
END{
  for(i=1;i<=count;i++){
    printf("%s ",b[i])
    for(j=2;j<=val;j++){
      printf("%s %s",c[b[i],j]?c[b[i],j]:0,j==val?ORS:OFS)
    }
  }
}' Input_file

输出如下:

DIA 55tyr  10  HOM  1  olig_al 
ALOP 66tel_128ryp_131dat  11  HET_HET_HET  3  alin_et_ivi_es_osi_et 
ANDY 12dou  13  WILD  4  sas_rar 
KOLIK 16dev  14  HET  6  levi_lol