Сопоставьте запись одного столбца в одном файле с записью столбца во втором файле, который состоит из списка

71
4

Мне нужно сопоставить одну запись столбца в одном файле с записью столбца во втором файле, который состоит из списка (в оболочке). Команда awk, которую я использовал, соответствует только первому слову списка и не просматривает весь список в поле столбца.

Файл 1 выглядит так:

chr1:725751 LOC100288069        
rs3131980 LOC100288069
rs28830877 LINC01128
rs28873693 LINC01128
rs34221207 ATP4A

Файл 2 выглядит так:

Annotation Total Genes With Ann Your Genes  With Ann)   Your Genes  No Ann) Genome  With Ann)   Genome  No Ann) ln
1 path hsa00190 Oxidative phosphorylation 55 55 1861 75 1139 5.9 9.64 0 0 ATP12A ATP4A ATP5A1 ATP5E ATP5F1 ATP5G1 ATP5G2 ATP5G3 ATP5J ATP5O ATP6V0A1 ATP6V0A4 ATP6V0D2 ATP6V1A ATP6V1C1 ATP6V1C2 ATP6V1D ATP6V1E1 ATP6V1E2 ATP6V1G3 ATP6V1H COX10 COX17 COX4I1 COX4I2 COX5A COX6B1 COX6C COX7A1 COX7A2 COX7A2L COX7C COX8A NDUFA5 NDUFA9 NDUFB3 NDUFB4 NDUFB5 NDUFB6 NDUFS1 NDUFS3 NDUFS4 NDUFS5 NDUFS6 NDUFS8 NDUFV1 NDUFV3 PP PPA2 SDHA SDHD TCIRG1 UQCRC2 UQCRFS1 UQCRH

Ожидаемый результат:

rs34221207  ATP4A hsa00190

(пожалуйста, извините форматирование - все столбцы разделены табуляцией, пока столбец с именами генов, 14 долларов, называется Геном...)

Моя команда такова:

awk 'NR==FNR{a[$14]=$3; next}a[$2]{print $0 "\t" a[$2]}' file2 file 1

Вся помощь будет очень признательна!

спросил(а) 2016-08-23T10:13:00+03:00 4 года, 3 месяца назад
1
Решение
59

Вам нужно обработать файлы в другом порядке и перебрать по списку:

awk 'NR==FNR{a[$2]=$1; next} {for(i=15;i<=NF;++i)if(a[$i]){print a[$i] "\t" $i "\t" $3}}' file1 file2

Объяснение:

NR - это глобальный счетчик числа записей, который увеличивает awk для каждой строки, считанной из каждого файла. FNR - это "номер записи" для каждого файла, который awk сбрасывает до 1 в первой строке каждого файла. Таким образом, условие NR==FNR истинно для строк в первом файле и false для строк в последующих файлах. Это awk идиома для выбора только первой информации о файле. В этом случае a[$2]=$1 хранит первый текст поля, введенный вторым текстом поля. next говорит awk прекратить короткое замыкание в текущей строке и читать и продолжать нормально обрабатывать следующую строку. next в конце первого предложения действия, подобный этому, функционально подобен условию ELSE для оставшегося кода, если awk имел такой синтаксис (которого это не так): NR==FNR{a[$2]=$1} ELSE {for... Более ясно и только немного меньше времени было бы писать вместо NR==FNR{a[$2]=$1}NR!=FNR{for...

Теперь во второе действие. Нет условие предшествующего ему не означает, что AWK будет делать это для каждой строки, которая не закорочено предыдущим next, то есть, все строки, кроме первого файлов - file2 только в этом случае. В файле file2 есть список потенциальных ключей, начинающихся в поле № 15 и проходящих до последнего поля. Встроенная переменная awk для последнего номера поля - NF (количество полей). Цикл for довольно понятен, а затем перебирает только эти номера полей. Для каждого из этих чисел i мы хотим знать, является ли текст в этом поле $i известным ключом из первого файла - задан a[$i], то есть вычисляется непустая (не false) строка. Если это так, то у нас есть первое поле file1 в a[$i], наше совпадающее file1 второе поле в $i и наше поле file2, представляющее интерес, в $3 (текст текущего файла 2-го поля). Распечатайте их в виде вкладок. next пример - это показатель эффективности, который останавливает всю обработку записи файла2, как только мы найдем совпадение. Если file2 список ключей может содержать дубликаты, и вы хотите дублировать выходные линии, если есть совпадение на такой дубликат, то вы должны удалить, что в прошлом в next.

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

ответил(а) 2016-08-24T16:21:00+03:00 4 года, 3 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема