Как сопоставить строки в двух файлах и заменить строки?

Как сопоставить строки в двух файлах и заменить строки?

У меня есть такой файл: (состоит из 308545 строк)

head output11.frq
 CHR               SNP   A1   A2          MAF  NCHROBS
   1      1:775852:T:C    T    C       0.1707     3444
   1     1:1120590:A:C    C    A      0.08753     3496
   1     1:1145994:T:C    C    T       0.1765     3496
   1     1:1148494:A:G    A    G       0.1059     3464
   1     1:1201155:C:T    T    C      0.07923     3496
...

И еще один файл (marker-info), который содержит первые 24 прокомментированные строки, разделенные запятыми, и выглядит следующим образом (всего 500593 строки):

1,742429,SNP_A-1909444,ss66079302,rs3094315,36.2,G,A,C,T,A,GCACAGCAAGAGAAAC[A/G]TTTGACAGAGAATACA,Sty,+,-,y,,,127,phs000018
1,769185,SNP_A-4303947,ss66273559,rs4040617,36.2,A,G,A,G,A,GCTGTGAGAGAGAACA[A/G]TGTCCCAATTTTGCCC,Sty,+,+,n,,,127,phs000018
1,775852,SNP_A-1886933,ss66317030,rs2980300,36.2,T,C,A,G,A,GAATGACTGTGTCTCT[C/T]TGAGTTAGTGAAGTCA,Nsp,-,+,y,,,127,phs000018
1,782343,SNP_A-2236359,ss66185183,rs2905036,36.2,C,T,C,T,A,CTCGATTTGTGTTCAA[C/T]ATATTTCATTTGTACC,Sty,-,-,n,,,127,phs000018
1,1201155,SNP_A-2205441,ss66174584,rs4245756,36.2,C,T,C,T,A,CCAGTGCTTTCAACCA[C/T]ACTCACTTTTCACTGT,Sty,+,+,n,,,127,phs000018
...

Я хочу заменить в output11.frq второй столбец на 5-й столбец в marker-info, который имеет совпадающее значение в 1-м и 2-м столбцах, поэтому для этого примера результат output11.frq будет выглядеть следующим образом:

1      rs2980300    T    C       0.1707     3444
1      rs4245756    T    C      0.07923     3496

Я попробовал сделать это, но получил пустой файл:

vi tst.awk
NR==FNR { map[$1,$2]=$5; next }
($1,$4) in map { $2=map[$1,$4]; print }


awk -f tst.awk FS=',' marker-info FS='\t' output11.frq  > output11X.frq

РЕДАКТИРОВАТЬ:

Я попробовал запустить это:

 vi test2.awk
 NR==FNR { map[$2]=$5 }
 NR!=FNR { split($4, x, ":"); if(x[2] in map){ $4=map[x[2]]; print }}

awk -f test2.awk FS=',' marker-info FS='\t' output11.frq > output11X.frq

но у меня получилось вот это:

head output11X.frq
 CHR               SNP   A1   A2          MAF  NCHROBS   rs41340551
   1      1:775852:T:C    T    C       0.1707     3444   rs41340551
   1     1:1120590:A:C    C    A      0.08753     3496   rs41340551
   1     1:1145994:T:C    C    T       0.1765     3496   rs41340551
...

решение1

Проблема с вашим скриптом заключалась в том, что вы пытались использовать строки 11:775852:T:Cв качестве ключей в карте, ключи которой имеют формат 775852.

Я исключил первый столбец из этой обработки, поскольку вы упомянули в комментарии, что не считаете его необходимым.

NR==FNR { map[$2]=$5 }
NR!=FNR { split($2, x, ":"); if(x[2] in map){ $2=map[x[2]]; print }}

Раньше я splitполучал нужную часть строки и добавлял условие, поскольку до тех пор, пока эта подстрока не будет обработана, нет возможности выполнить нужный вам поиск.

Похоже, это работает так, как и требовалось:

[gnubeard@mothership: ~/dna]$ awk -f test.awk FS=',' marker-info FS=' ' output11.frq
 1  rs2980300 T C 0.1707 3444
 1  rs4245756 T C 0.07923 3496

Убедитесь, что поля, которые у вас есть, соответствуют столбцам, которые, как вы думаете, у вас есть. Если вы хотите, чтобы вывод был разделен табуляцией, вы можете задать переменную OFSво второй половине скрипта, например так:NR!=FNR { OFS="\t"; split($2, x, ":"); if(x[2] in map){ $2=map[x[2]]; print }}

EDIT: Я изменил FSпеременную в команде, чтобы изменить разделитель для output11.frq на пробел. Это предотвратит возню с количеством вкладок.

Связанный контент