通过在特定列上拆分字符串以匹配bash中的另一个数组来对数组进行AWK排序

时间:2019-02-07 18:39:21

标签: arrays bash awk

我有一个数组a,其以下几行

rs6605071   chr1:962943 C   ENSG00000188976 ENST00000487214
rs6605071   chr1:962943 C   ENSG00000187961 ENST00000622660
rs6605071   chr1:962943 C   84069   NM_001160184.1
rs6605071   chr1:962943 C   339451  NC_006462594.2
rs6605071   chr1:962943 C   339451  XR_001737138.1
rs6605071   chr1:962943 C   339451  XM_006710600.3

和另一个有以下行的有序数组b

NC
NG
NM
NP
NR
XM
XP
XR
WP

我想对数组a中的行进行排序以匹配列5上数组b的顺序,以获得所需的输出:

rs6605071   chr1:962943 C   339451  NC_006462594.2
rs6605071   chr1:962943 C   84069   NM_001160184.1
rs6605071   chr1:962943 C   339451  XM_006710600.3
rs6605071   chr1:962943 C   339451  XR_001737138.1
rs6605071   chr1:962943 C   ENSG00000188976 ENST00000487214
rs6605071   chr1:962943 C   ENSG00000187961 ENST00000622660

我试图通过在第5列上拆分来执行以下命令,但它正在打印空白行:

awk -F '\t' -v OFS='\t' 'FNR==NR{split(a[$5],t,"_"); t[1]=$0;next}
{print a[$1]}' <(printf '%s\n' "${a[@]}") <(printf '%s\n' "${b[@]}")

能否请您告诉我为什么我的命令不起作用?正则表达式的部分匹配会起作用吗?

编辑1 :更改数组a,使其包含可以包含数组b中的多个代码的行

rs6605071   chr1:962943 C   ENSG00000188976 ENST00000487214
rs6605071   chr1:962943 C   ENSG00000187961 ENST00000622660
rs6605071   chr1:962943 C   84069   NM_001160184.1
rs6605071   chr1:962943 C   339451  NC_006462594.2
rs6605071   chr1:962943 C   ENSG00000135234 ENST00000624144
rs6605071   chr1:962943 C   339451  XR_001737138.1
rs6605071   chr1:962943 C   334324  NC_006462632.2
rs6605071   chr1:962943 C   84333   NM_004353462.1
rs6605071   chr1:962943 C   339451  XM_006710600.3

预期输出:

rs6605071   chr1:962943 C   334324  NC_006462632.2
rs6605071   chr1:962943 C   339451  NC_006462594.2
rs6605071   chr1:962943 C   84069   NM_001160184.1
rs6605071   chr1:962943 C   84333   NM_004353462.1
rs6605071   chr1:962943 C   339451  XM_006710600.3
rs6605071   chr1:962943 C   339451  XR_001737138.1
rs6605071   chr1:962943 C   ENSG00000188976 ENST00000487214
rs6605071   chr1:962943 C   ENSG00000187961 ENST00000622660
rs6605071   chr1:962943 C   ENSG00000135234 ENST00000624144

编辑2 :由于下面的RavinderSingh13提供的答案不能完全回答我的问题,因此我将重新询问如何使用AWK执行此类任务的问题。

谢谢。

1 个答案:

答案 0 :(得分:2)

我在这里假设您要按顺序打印两个数组的匹配字段,然后也要打印数组a中剩余的不匹配项,如果是这种情况,那么下面的内容可能会对您有所帮助。

在此处创建数组:

declare -a a=("rs6605071   chr1:962943 C   ENSG00000188976 ENST00000487214
rs6605071   chr1:962943 C   ENSG00000187961 ENST00000622660
rs6605071   chr1:962943 C   84069   NM_001160184.1
rs6605071   chr1:962943 C   339451  NC_006462594.2
rs6605071   chr1:962943 C   339451  XR_001737138.1
rs6605071   chr1:962943 C   339451  XM_006710600.3")
declare -a b=("NC
NG
NM
NP
NR
XM
XP
XR
WP")

现在运行以下代码:

awk -v OFS='\t' '
FNR==NR{
  split($5,a,"_")
  array[a[1]]=$0
  next
}
($1 in array) {
  print array[$0]
  b[$1]
}
END{
  for(i in b){
    delete array[i]
  }
  for(j in array){
    print array[j]
  }
}' <(printf '%s\n' "${a[@]}") <(printf '%s\n' "${b[@]}")

输出如下。

rs6605071   chr1:962943 C   339451  NC_006462594.2
rs6605071   chr1:962943 C   84069   NM_001160184.1
rs6605071   chr1:962943 C   339451  XM_006710600.3
rs6605071   chr1:962943 C   339451  XR_001737138.1
rs6605071   chr1:962943 C   ENSG00000188976 ENST00000487214
rs6605071   chr1:962943 C   ENSG00000187961 ENST00000622660