在带有awk的bash中使用另一个有序数组模式对多行数组进行排序

时间:2019-02-11 03:11:24

标签: arrays awk

根据我之前在my old post上发布的帖子,由于它没有完全回答我的问题。我想知道如何对数组a中包含多行特定标记代码的数组b进行排序。

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

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

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

NC
NG
NM
NP
NR
XM
XP
XR
WP

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

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

在我以前的帖子中已经提出了以下命令:

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   334324  NC_006462632.2  stuff
rs6605071   chr1:962943 C   84069   NM_001160184.1  stuff
rs6605071   chr1:962943 C   339451  XM_006710600.3  stuff
rs6605071   chr1:962943 C   339451  XR_001737138.1  stuff
rs6605071   chr1:962943 C   ENSG00000188976 ENST00000487214 stuff
rs6605071   chr1:962943 C   ENSG00000187961 ENST00000622660 stuff
rs6605071   chr1:962943 C   ENSG00000135234 ENST00000624144 stuff

如您所见,有些行中缺少NMNC。您能否告诉我如何更新此命令以输出所需的结果?

谢谢。

3 个答案:

答案 0 :(得分:2)

能否请您尝试以下。我现在已经更改了解决方案。为什么呢?因为尚不清楚您要从数组a打印所有NC的值,所以现在更改了逻辑。它会继续将字符串NCNV的值串联起来,并在数组b左右进行检查时,将打印出它的所有值(来自数组a)。

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

答案 1 :(得分:2)

这是CharSequence sequence = Html.fromHtml(p, this, null); SpannableStringBuilder stringBuilder = new SpannableStringBuilder(sequence); contentNews.setText(stringBuilder); contentNews.setMovementMethod(LinkMovementMethod.getInstance()); awk解决方案

sort

答案 2 :(得分:1)

您可以尝试这个awk。将依赖于内存(大文件上的问题),因为在字典中加载字典以及整个文件都需要加载。需要使用ANU的GNU版本。

awk 'FNR==NR{ Dct[$1] = Idx++; next }
   {
   Ctg = $5; sub( /_.*/, "", Ctg )
   Indice = ( Ctg in Dct ) ? Dct[Ctg] : Idx
   Lines[Ln++] = Indice " " $0
   }

   END {
     asort( Lines )
     for( Idx=0; Idx<Ln; Idx++) {
        Temp = Lines[Idx]
        sub( /^[^ ]* /, "", Temp)
        print Temp
        }
     }
   ' Array.B Array.A

与@karakfa相同的原理,但仅适用于awk