Сортировать массив с несколькими строками, используя другой упорядоченный массив в bash с помощью awk. - PullRequest
0 голосов
/ 11 февраля 2019

После моего предыдущего поста на моего старого поста и так как он не полностью ответил на мой вопрос.Я хотел бы знать, как я могу отсортировать мой массив 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 в соответствии с порядком массива b в столбце 5чтобы получить желаемый результат:

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

Как вывидите, отсутствуют строки, содержащие NM и NC.Не могли бы вы сказать мне, как я могу обновить эту команду для вывода желаемого результата?

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 11 февраля 2019

здесь awk с sort решением

$ awk 'NR==FNR{a[$1]=NR; next} 
          {k=substr($5,1,2); 
           print (k in a)?a[k]:99,NR "\t" $0}' <(printf '%s\n' "${b[@]}") <(printf '%s\n' "${a[@]}") | 
  sort -n | cut -f2-

rs6605071   chr1:962943 C   339451  NC_006462594.2  stuff
rs6605071   chr1:962943 C   334324  NC_006462632.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
0 голосов
/ 11 февраля 2019

Вы можете попробовать это awk.Будет зависеть от памяти (проблема с огромным файлом), поскольку загружает словарь, а также полный файл во временном массиве.Нужна версия GNU для использования asort.

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

0 голосов
/ 11 февраля 2019

Не могли бы вы попробовать следующее.Я немного изменил решение сейчас.Почему, потому что не было ясно, что вы хотите напечатать ВСЕ значения, например NC из массива a, поэтому я изменил логику сейчас.Где он будет хранить конкатенацию значений для себя для строки NC ИЛИ NV, и когда он проверяет это в массиве 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[@]}")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...