2012-03-28 3 views
2

У меня есть две следующие текстовые файлы:Объединение двух текстов, которые разделяют ОБРАЗЕЦ с использованием Баш кода

Первый:

chr10 1000 1001 DEL 2.4807 chr10 7443 8978 
chr10 1005 1008 DEL 1.2799 chr10 7321 8778 

Вторая:

chr13 3456 6746 chr10 7443 8978 
chr13 6453 8767 chr10 7321 8778 

Мы можем видеть, что они разделяют a образец:

chr10 7443 8978 
chr10 7321 8778 

по этой схеме, как я могу объединить их в:

chr10 1000 1001 DEL 2.4807 chr10 7443 8978 chr13 3456 6746 
chr10 1005 1008 DEL 1.2799 chr10 7321 8778 chr13 6453 8767 

БЛАГОДАРЯ

редактировать: Я пытался Grep как:

cat text1|grep -f `cat text2|awk '{print $4"\t"$5"\t"$6}'` 

, но он не работает

+2

[Что вы пробовали] (http://mattgemmell.com/2008/12/08/what-have-you-tried/)? – Graham

+0

Вам нужно будет предоставить более подробную информацию. Возможно, сам Bash сможет справиться с этим, но может быть проще использовать общие инструменты, которые вы можете вызвать из bash, например awk или perl. Кроме того, какова ваша терпимость? Я вижу общие «последние три поля», если вы игнорируете пробелы. Это тот шаблон, который вы хотите? Последние три поля? Всегда и только три? – ghoti

+0

Я думаю, что, возможно, использование «grep». Но все же не может найти – user815408

ответ

3

Вы можете сделать три поля в одном слоте awk. Вот доказательство:

[[email protected] ~]$ cat file1 
chr10 1000 1001 DEL 2.4807 chr10 7443 8978 
chr10 1005 1008 DEL 1.2799 chr10 7321 8778 
[[email protected] ~]$ cat file2 
chr13 3456 6746 chr10 7443 8978 
chr13 6453 8767 chr10 7321 8778 
[[email protected] ~]$ awk 'NR == FNR { what[$(NF-2),$(NF-1),$(NF)] = $0; next; } { printf("%s %s\n", what[$(NF-2),$(NF-1),$(NF)], $0); }' file1 file2 
chr10 1000 1001 DEL 2.4807 chr10 7443 8978 chr13 3456 6746 chr10 7443 8978 
chr10 1005 1008 DEL 1.2799 chr10 7321 8778 chr13 6453 8767 chr10 7321 8778 
[[email protected] ~]$ 

Если вы хотите файлы в другом порядке, просто изменить порядок $0 и what[] в Е().

Обратите внимание, что это предполагает, что все в порядке с загрузкой всего содержимого первого файла в массив в памяти. Вероятно, не следует использовать для файлов с миллионами строк, но это будет полностью зависеть от системы, в которой вы ее используете.

Как это работает?

Сценарий awk имеет два основных раздела, каждый из которых фигурных скобок. Первый раздел ТОЛЬКО запускается, если NR (текущий номер записи всех прочитанных данных) соответствует FNR (номер записи в текущем файле). Другими словами, он действует только на первый файл. Первый файл загружается в память в ассоциативном массиве, индекс которого является последним тремя полями строки.

Второй раздел действует на каждый последующий файл после первого. Он просто печатает текущую строку, но добавляет ее к содержимому массива (согласованному в первом разделе), которое соответствует последним трем полям текущей строки.

+0

Большое спасибо. оно работает. но можете ли вы немного объяснить о «какой» функции в скрипте? – user815408

+0

'what' не является функцией, это массив. Это индекс состоит из трех важных значений из файла1, а значения - это полные строки. Для каждого элемента в файле1 предполагается, что индекс (последние три поля) существует в файле2. – ghoti

+0

Просто выполните следующие действия: Я обнаружил, что если в файле 1 есть несколько строк, которые имеют один и тот же шаблон (последние три поля), скрипт будет случайно выбрать один. Хотя я хочу, чтобы все линии разделяли шаблон ... – user815408

Смежные вопросы