Можно использовать awk
. Поместите следующее в сценарий, script.awk
:
FNR == NR {
f1[$1,$2,$4] = $0
f1_c14[$1,$2,$4] = 1
f1_c5[$1,$2,$4] = $5
next
}
f1_c14[$1,$2,$4] {
if ($5 != f1_c5[$1,$2,$4]) print f1[$1,$2,$4];
}
f1[$1,$2,$4] {
if ($5 != f1_c5[$1,$2,$4]) print $0;
}
Теперь выполните его как это:
$ awk -f script.awk file1 file2
sc2/80 20 . A T 86 PASS N=2 F=5;U=4
sc2/80 20 . A C 80 PASS N=2 F=5;U=4
sc2/60 55 . G T 76 PASS N=2 F=5;U=4
sc2/60 55 . G C 72 PASS N=2 F=5;U=4
Сценарий работает следующим образом. Этот блок создает 3 массива, f1
, f1_c14
, и f1_c5
. f1
содержит все строки file1 в массиве, индексированное использование содержания столбцов 1, 2, и 4 от file1. f1_c14
другой массив с тем же индексом (1, 2, и 4's содержание) и значение 1
. 3-й массив использует тот же индекс в качестве 1-х 2 со значением 5-го столбца от file1.
FNR == NR {
f1[$1,$2,$4] = $0
f1_c14[$1,$2,$4] = 1
f1_c5[$1,$2,$4] = $5
next
}
Следующий блок ответственен за печать строк из 1-го файла, file1
при условиях, от которых столбцы 1, 2, и 4 соответствуют столбцам file2
, И это будет onlu распечатать строку от file1
если 5-е столбцы file1
и file2
не соответствовать.
f1_c14[$1,$2,$4] {
if ($5 != f1_c5[$1,$2,$4]) print f1[$1,$2,$4];
}
3-й блок ответственен за печать связанной строки от file2
в массиве существует соответствующая строка f1
для file2
столбцы 1, 2, и 4. Снова это только печатает, если 5-е столбцы не соответствуют.
f1[$1,$2,$4] {
if ($5 != f1_c5[$1,$2,$4]) print $0;
}
Выполнение вышеупомянутого сценария как так:
$ awk -f script.awk file1 file2
sc2/80 20 . A T 86 PASS N=2 F=5;U=4
sc2/80 20 . A C 80 PASS N=2 F=5;U=4
sc2/60 55 . G T 76 PASS N=2 F=5;U=4
sc2/60 55 . G C 72 PASS N=2 F=5;U=4
Можно использовать column
управляйте для чистки вывода немного:
$ awk -f script.awk file1 file2 | column -t
sc2/80 20 . A T 86 PASS N=2 F=5;U=4
sc2/80 20 . A C 80 PASS N=2 F=5;U=4
sc2/60 55 . G T 76 PASS N=2 F=5;U=4
sc2/60 55 . G C 72 PASS N=2 F=5;U=4
Это использует awk
способность циклично выполниться через файлы конкретным способом. Вот, мы - цикличное выполнение через файлы и когда мы находимся на строке, это из первого файла, file
, мы хотим выполнить конкретный блок кода на этой строке от file1
.
Этот пример показывает что FNR == NR
делает, когда мы даем ему 2 моделируемых файла. У каждого есть 4 строки в нем, в то время как другой имеет 5 строк:
$ awk 'BEGIN {print "NR\tFNR\tline"} {print NR"\t"FNR"\t"$0}' \
<(seq 1 4) <(seq 1 5)
NR FNR line
1 1 1
2 2 2
3 3 3
4 4 4
5 1 1
6 2 2
7 3 3
8 4 4
9 5 5
другие блоки
Другие блоки, f1_c14[$1,$2,$4]
И f1[$1,$2,$4]
только выполненный, когда значения от тех элементов массива имеет значение.
Я не могу придумать способ использования простого регулярного выражения, поскольку то, что вы делаете, немного сложно.
В языке вроде Ruby вы можете разбить строки на массив слов, разделенных пробелами, с помощью регулярного выражения ( \ s +
) и получить ] пересечение ( и
) двух результирующих массивов.
"30 mutation alanine for valine".split( /\s+/ ) & "alanine at position 30".split( /\s+/ )
=> ["30", "alanine"]
Пробелы используются по умолчанию для разделения в Ruby, поэтому их можно сократить до
"30 mutation alanine for valine".split & "alanine at position 30".split
Может быть, wdiff
может вам помочь? Поместите строки в два файла, а затем сравните их с wdiff
:
echo "30 mutation alanine for valine" > file1
echo "alanine at position 30" > file2
wdiff -t file1 file2
Снимок экрана вывода:
Вот решение awk
:
$ awk '{for(i=1;i<=NF;i++){a[$i]++}}
END {
for(i in a) {
if(a[i] > 1) {
print i
}
}
}' file1 file2
30
alanine
Вы можете проверить слова, которые появляются в обеих строках:
$ comm -12 <(sed 's/ /\n/g' <<<$str1 | sort) <(sed 's/ /\n/g' <<<$str2 | sort )
30
alanine
Команда comm
сравнивает файлы. С флагами -1
и -2
он будет печатать те строки, которые находятся в обоих файлах.
sed 's / / \ n / g' <<< $ str1 | sort
: это просто заменяет все пробелы на новые строки в $ str1
, выводит на стандартный вывод, который затем передается через sort
, потому что comm
нуждается в своих входных файлах быть отсортированным. Подробнее о формате <<< $ var
см. Bash: Here Strings .
Формат <(команда)
называется подстановкой процесса, подробнее об этом здесь .
Конечным результатом приведенной выше команды будет список всех слов, которые встречаются в обеих строках.