awk сопоставьте три столбца из двух файлов и добавьте соответствующие строки в новый файл

#linux #awk

Вопрос:

Есть много постов, похожих на этот. Несколько часов в поисках проблем я в отчаянии, так как кажется, что все должно быть просто.

У меня есть один файл, который выглядит так:

 tig00000005 15310 16162 XP_012153921.1 NW_003797090.1 LOC105664333 PREDICTED: elastin-like tig00000005 23339 23974 XP_012152584.1 NW_003797083.1 LOC100878991 PREDICTED: LOW QUALITY PROTEIN tig00000005 24600 25138 XP_012143166.1 NW_003797196.1 LOC100881279 PREDICTED: ankyrin-2 isoform X2 tig00000005 2685 4511 XP_012144644.1 NW_003797249.1 LOC105662970 PREDICTED: fibrinogen alpha chain-like isoform X2 tig00000005 28923 29432 XP_012148395.1 NW_003797444.1 LOC100881617 PREDICTED: eukaryotic translation initiation factor 4 gamma 3-like isoform X12 tig00000005 32415 34324 XP_012153921.1 NW_003797090.1 LOC105664333 PREDICTED: elastin-like  

И второй файл, который выглядит так:

 tig00000005 maker gene 15310 16162 .   . ID=snap_masked-tig00000005-processed-gene-0.2;Name=snap_masked-tig00000005-processed-gene-0.2 tig00000005 maker gene 16764 17237 .   . ID=snap_masked-tig00000005-processed-gene-0.3;Name=snap_masked-tig00000005-processed-gene-0.3 tig00000005 maker gene 23339 23974 .   . ID=snap_masked-tig00000005-processed-gene-0.4;Name=snap_masked-tig00000005-processed-gene-0.4 tig00000005 maker gene 24600 25138 . - . ID=snap_masked-tig00000005-processed-gene-0.10;Name=snap_masked-tig00000005-processed-gene-0.10 tig00000005 maker gene 25472 26900 .   . ID=snap_masked-tig00000005-processed-gene-0.5;Name=snap_masked-tig00000005-processed-gene-0.5  

Я хотел бы сопоставить столбцы 1, 2 и 3 в первом файле с 1, 4 и 5 во втором, и если они совпадают, добавьте данные второго файла в первый файл, например так:

 tig00000005 15310 16162 XP_012153921.1 NW_003797090.1 LOC105664333 PREDICTED: elastin-like tig00000005 maker gene 15310 16162 .   . ID=snap_masked-tig00000005-processed-gene-0.2;Name=snap_masked-tig00000005-processed-gene-0.2  

Пример кода, который не сработал:

 awk 'OFS="t"; FS="t"; NR==FNR{a[$1,$2,$3]=$0; next} (($1,$4,$5) in a){print $0,a[$0]}' file 1 file 2  awk 'OFS="t"; FS="t"; NR==FNR{a[$1,$2,$3]=($1,$4,$5)} {print $0,a[$0]}' file 1 file 2   

Первый выводит файл с каждой строкой из файла 1, за которым следует (не добавленный) файл 2, второй код выдает ошибки, связанные с функцией=. Я пробовал любую перестановку этого, какую только могу себе представить. Спасибо вам за любую помощь, которую вы можете оказать

Ответ №1:

Пара небольших изменений в первом awk сценарии OP:

 # old:  awk 'OFS="t"; FS="t"; NR==FNR{a[$1,$2,$3]=$0; next} (($1,$4,$5) in a){print $0,a[$0]}' file1 file2  # new - add BEGIN block, modify print statement:  awk 'BEGIN {FS=OFS="t"} NR==FNR{a[$1,$2,$3]=$0; next} (($1,$4,$5) in a){print a[$1,$4,$5],$0}' file1 file2  

Измененный awk сценарий генерирует:

 tig00000005 15310 16162 XP_012153921.1 NW_003797090.1 LOC105664333 PREDICTED: elastin-like tig00000005 maker gene 15310 16162 .   . ID=snap_masked-tig00000005-processed-gene-0.2;Name=snap_masked-tig00000005-processed-gene-0.2 tig00000005 23339 23974 XP_012152584.1 NW_003797083.1 LOC100878991 PREDICTED: LOW QUALITY PROTEIN tig00000005 maker gene 23339 23974 .   . ID=snap_masked-tig00000005-processed-gene-0.4;Name=snap_masked-tig00000005-processed-gene-0.4 tig00000005 24600 25138 XP_012143166.1 NW_003797196.1 LOC100881279 PREDICTED: ankyrin-2 isoform X2 tig00000005 maker gene 24600 25138 . - . ID=snap_masked-tig00000005-processed-gene-0.10;Name=snap_masked-tig00000005-processed-gene-0.10  

Ответ №2:

Вот так?

 awk 'NR==FNR{a[$1" "$2" "$3]=$0; next}; {if($1" "$4" "$5 in a){print a[$1" "$4" "$5],$0}}' file1 file2 tig00000005 15310 16162 XP_012153921.1 NW_003797090.1 LOC105664333 PREDICTED: elastin-like tig00000005 maker gene 15310 16162 .   . ID=snap_masked-tig00000005-processed-gene-0.2;Name=snap_masked-tig00000005-processed-gene-0.2 tig00000005 23339 23974 XP_012152584.1 NW_003797083.1 LOC100878991 PREDICTED: LOW QUALITY PROTEIN tig00000005 maker gene 23339 23974 .   . ID=snap_masked-tig00000005-processed-gene-0.4;Name=snap_masked-tig00000005-processed-gene-0.4 tig00000005 24600 25138 XP_012143166.1 NW_003797196.1 LOC100881279 PREDICTED: ankyrin-2 isoform X2 tig00000005 maker gene 24600 25138 . - . ID=snap_masked-tig00000005-processed-gene-0.10;Name=snap_masked-tig00000005-processed-gene-0.10  

Чтобы записать в новый файл, просто сделайте awk 'NR==FNR{a[$1" "$2" "$3]=$0; next}; {if($1" "$4" "$5 in a){print a[$1" "$4" "$5],$0}}' file1 file2 gt; file3

Комментарии:

1. Это не работает, так a bc ab c как и объединение abc , и некоторые из объединяемых полей не имеют фиксированной ширины. Если вы замените пробелы запятыми между значениями, объединяемыми для формирования индексов массива (например $1,$2,$3 , вместо $1 $2 $3 ), это позволит избежать этой проблемы.

2. Кстати, тестовый запуск с запятыми дал тот же результат, что и пробелы — три значения работали вместе. Использование a[$1" "$2" "$3] сработало.

3. Вы использовали a[$1,$2,$3] или цитировали запятые? Без кавычек запятая действует как SUBSEP "The character used to separate multiple subscripts in array elements, ..."

4. Я их не цитировал.