У меня есть два файла, разделенных табуляцией, которые выглядят следующим образом:
file1:
NC_008146.1 WP_011558474.1 1155234 1156286 44173
NC_008146.1 WP_011558475.1 1156298 1156807 12
NC_008146.1 WP_011558476.1 1156804 1157820 -3
NC_008705.1 WP_011558474.1 1159543 1160595 42748
NC_008705.1 WP_011558475.1 1160607 1161116 12
NC_008705.1 WP_011558476.1 1161113 1162129 -3
NC_009077.1 WP_011559727.1 2481079 2481633 8
NC_009077.1 WP_011854835.1 1163068 1164120 42559
NC_009077.1 WP_011854836.1 1164127 1164636 7
file2:
NC_008146.1 GCF_000014165.1_ASM1416v1_protein.faa
NC_008705.1 GCF_000015405.1_ASM1540v1_protein.faa
NC_009077.1 GCF_000016005.1_ASM1600v1_protein.faa
Я хочу сопоставить столбец 1 файла1 с файлом2 и заменить себя соответствующей записью столбца 2 файла 2. Вывод будет выглядеть следующим образом:
GCF_000014165.1_ASM1416v1_protein.faa WP_011558474.1 1155234 1156286 44173
GCF_000014165.1_ASM1416v1_protein.faa WP_011558475.1 1156298 1156807 12
GCF_000014165.1_ASM1416v1_protein.faa WP_011558476.1 1156804 1157820 -3
GCF_000015405.1_ASM1540v1_protein.faa WP_011558474.1 1159543 1160595 42748
GCF_000015405.1_ASM1540v1_protein.faa WP_011558475.1 1160607 1161116 12
GCF_000015405.1_ASM1540v1_protein.faa WP_011558476.1 1161113 1162129 -3
GCF_000016005.1_ASM1600v1_protein.faa WP_011559727.1 2481079 2481633 8
GCF_000016005.1_ASM1600v1_protein.faa WP_011854835.1 1163068 1164120 42559
GCF_000016005.1_ASM1600v1_protein.faa WP_011854836.1 1164127 1164636 7
Ответы:
Вы можете сделать это очень легко с
awk
:Или, так как это выглядит как разделенный табуляцией файл:
Это предполагает, что каждый
NC_*
идентификатор RefSeq ( ) вfile1
имеет соответствующую запись вfile2
.объяснение
NR==FNR
: NR - номер текущей строки, FNR - номер строки текущего файла. Они будут идентичны только воfile2
время чтения 1-го файла (здесь ).a[$1]=$2; next
: если это первый файл (см. выше), сохраните 2-е поле в массиве, ключом которого является 1-е поле. Затем перейдите кnext
линии. Это гарантирует, что следующий блок не будет выполнен для 1-го файла.{$1=a[$1]; print}
: теперь, во втором файле, установите для 1-го поля значение, которое было сохранено в массивеa
для 1-го поля (то есть, связанное значение изfile2
), и выведите полученную строку.источник
NR == FNR
не работает правильно, когда первый файл пуст. См. Этот и связанный ответ для обходного путиfile2
и неfile1
пусто. Разумное поведение, когдаfile2
пусто, чтобы сообщить о содержимомfile1
. Проблема вNR == FNR
том, что связанный с ним код выполняется на содержимомfile1
file2
Нет необходимости в awk, если файлы отсортированы, вы можете использовать coreutils join:
Вывод:
Если ваши файлы не отсортированы, вы можете либо отсортировать их сначала (
sort file1 > file1.sorted; sort file2 > file2.sorted
), а затем использовать приведенную выше команду, либо, если ваша оболочка поддерживает<()
конструкцию (bash делает), вы можете сделать:источник
Протестировано с приведенной ниже командой и работает нормально
вывод
источник