Частично сопоставить слова из двух разных файлов и извлечь строки sed, awk, grep? - PullRequest
0 голосов
/ 16 ноября 2018

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

Файл1:

smt_hsa_3150    932
smt_hsa_28592   682
smt_hsa_5184    657
smt_hsa_430 648
smt_hsa_14100   648
smt_hsa_96 648

Файл 2:

chr11 5933549 5933577 29 + hsa_smt_028592
chr11 45693060 45693086 27 - hsa_smt_000059
chr11 45699803 45699832 30 - hsa_smt_000087
chr2 131291172 131291197 26 - hsa_smt_000096

Мне нужно сопоставить smt_hsa_28592 или 28592 с hsa_smt_028592 или 028592. и затем извлечь в новый файл строку из второго файла плюс номер из 2-го столбца 1-го файла.

output:

chr11 5933549 5933577 29 + hsa_smt_028592 682   
chr2 131291172 131291197 26 - hsa_smt_000096 648

Поскольку я новичок в программировании на awk / sed, я сначала попытался изменить имя первого столбца 1-го файла с smt_hsa_3150 на hsa_smt_3150, но когда я выполняю

awk '{gsub("smt","hsa")}1'

тогда я не могу использовать тот же код, чтобы изменить только второй "hsa".Вторая проблема заключается в том, как я могу сопоставить hsa_smt_028592 с smt_has_28592 или smt_hsa_96 с hsa_smt_000096.

1 Ответ

0 голосов
/ 16 ноября 2018

Для развлечения используйте join:

join -11 -26 -o 2.1,2.2,2.3,2.4,2.5,1.1,1.2 <(awk -F' +|_' '{printf "hsa_smt_%06s %s\n", $3, $4}' file1.txt | sort -k1) <(sort -k6 file2.txt)

Команда awk форматирует первый столбец вашего файла1 в том же формате, что и файл2.Затем мы объединяем два файла (сначала нам нужно отсортировать их оба).


awk -F' *|_' -> Я разделяю на несколько пробелов и символ "_"

'{printf "hsa_smt_%06s %s\n", $3, $4}' -> Я печатаю hsa_smt_ <третий столбец как целое число шириной 6> <4-й столбец>.При необходимости Awk добавит начальные нули

sort -k6 file2 или awk ... | sort -k1 Я сортирую файлы по 6-му или 1-му столбцу

join -11 -26 -o 2.1,2.2,2.3,2.4,2.5,1.1,1.2 Я присоединяю файлы по первому столбцу для файла 1 (-11) и 6-й столбец для файла 2 (-26), затем я упорядочиваю столбцы (2.1 -> 1-й столбец файла2 и т. Д.) *


Чистое решение awk:

awk 'NR==FNR{split($1,s,"_");smt[s[3]+0]=$2;next}{split($6,s,"_");k=s[3]+0}k in smt{print $0, smt[k]}' file1.txt file2.txt

В этом решении я разделяю smt_hsa_xxx и hsa_smt_xxx, конвертирую 3-ю часть в целые, чтобы я мог их сравнить.


NR==FNR{split($1,s,"_");smt[s[3]+0]=$2;next} этот блок будет выполняться только для файла1из-за NR==FNR условия .Он разбивает первый столбец, преобразует идентификатор smt_hsa в целое число (выполнение +0 - классический способ преобразования строки в целое число в awk), затем сохраняет второй столбец внутри массива с именем smt.

next; предотвращает выполнениедругие блоки для файла1

{split($6,s,"_");k=s[3]+0} этот блок будет разбивать шестой столбец файла2, преобразовать идентификатор в целое число.Мы могли бы использовать «+ | _» в качестве разделителя, чтобы избежать разделения столбцов (см. Первое решение).

k in smt{print $0, smt[k]} проверит, является ли id ключом массива smt.Затем он печатает строку из file2 и второго столбца file1 (который был сохранен в smt)


Я почти уверен, что второе решение более производительно, но может быть жадным в памяти.

Оба дают одинаковый вывод, порядок строк может отличаться:

chr11 5933549 5933577 29 + hsa_smt_028592 682
chr2 131291172 131291197 26 - hsa_smt_000096 648
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...