Можно использовать многомерный массив:
awk 'FNR==NR{a[$1,$2,$4,$5]=$0;next}{if(b=a[$1,$2,$4,$5]){print b;print}}' file1 file2
FNR
(номер документа записи), равно NR
когда awk обрабатывает первый файл.
a[$1,$2]=$0
совпадает с a[$1 SUBSEP $2]=$0
или a[$1"\034"$2]=$0
, и ($1,$2)in a
совпадает с ($1 SUBSEP $2)in a
или ($1"\034"$2)in a
.
Вы могли также заменить if(b=a[$1,$2,$4,$5]){print b;print}
с if(($1,$2,$4,$5)in a){print a[$1,$2,$4,$5];print}
. Если !("index" in a)
, a["index"]
похож a["index"]=""
.
Я знаю, что Вы сказали, что не хотели Perl или решение Python, но это могло бы быть полезно для кого-то еще (и действительно действительно необходимо выучить один из тех языков при выполнении биоинформатики).
perl -ane '$f=$F[0].$F[1]; print "$k{$f}$_" if $k{$f}; $k{$f}=$_;' file1 file2
ОБЪЯСНЕНИЕ:
-a
опция заставит Perl разделять вход на @F
массив, -n
средства читают входные файлы линию за линией и -e
означает, "запускает скрипт, который я даю на командной строке".
Так, $f
установлен на конкатенацию первого ($F[0]
) и второй ($F[1]
) поля. $k{$f}=$_
средства сохраняют текущую строку ($_
) как значение в хеше (ассоциативные массивы в Perl) названный k
с ключом $f
. Поскольку мы прочитываем файлы, печатаем текущую строку и значение $k{$f}
если то значение существует. Другими словами, если мы уже видели строку, которая имеет те же два первых поля, распечатайте ту строку и текущую.
Если можно гарантировать, что каждый файл, как предполагается, имеет уникальные записи. Отсортируйте файлы с sort -u
свяжите файлы. Отсортируйте снова без -u
и затем поиск дублирующихся записей.
Я записал бы небольшой сценарий, но я не могу сделать этого из головы. Но это не должно быть к твердому, учитывая мой подход.
У меня есть консоль передо мной теперь.Вот:
rm -rf all; sort -u file1 > all; sort -u file2 >> all
sort all | uniq --all-repeated=separate -w 32
Если file1
file2
уже отсортированы и не содержат дублирующиеся записи, можно использовать эту команду:
sort -m file1 file2 | uniq --all-repeated=separate -w 32
О, похож, это не совсем, что Вы спросили, так как я сравниваю целые строки. Возможно, кто-то еще найдет это полезным все же.
Вы хотите распечатать пересечение этих двух файлов, не переупорядочивая их (таким образом, это не пересечение набора)? Я искал бы строковые алгоритмы подобия и рассматривал бы каждую строку как букву. Необходимо будет изменить алгоритм для отслеживания, какие буквы (строки) являются тем же и которые отличаются. Большая проблема состоит в том, что порядок является значительным, но положение не. Кроме того, можно найти легче массажировать данные путем перезаписи его для отбрасывания полей, о которых Вы не заботитесь. (Или записать функцию сравнения, которая игнорирует эти поля.)
Вы рассмотрели Python или жемчуг? Я услышал, что они популярны в поле биоинформатики. И это действительно походит на задачу программирования.
if(b=a[$1,$2,$4,$5])
но гдеb
определенный? Это - неявное определение? – mike 27.08.2013, 14:59=
присвоение, не сравнение. – Lri 27.08.2013, 15:12a
имеет индекс как$1"\034"$2"\034"$4"\034"$5
,a[$1,$2,$4,$5]
возвращает значение элемента в том индексе. Иначеa[$1,$2,$4,$5]
добавляет новый элемент в том индексе, значение которого является пустой строкой, иb
присвоен пустой строке, которая оценивает ко лжи. – Lri 28.08.2013, 07:16