Короткийgawkподход:
awk '(index($1, $2) !=0 && length($2) >= 4) || (index($2, $1) !=0 && length($1) >= 4)' file
Вывод:
023q 023q023q
0adc 0adc0adc
123456 123456
abcde abcdefg
index(in, find)
Поиск в строке inпервого вхождения строки findи вернуть позицию в символах, где вхождение начинается со строки in.
Для болеесложногослучая, когда нам нужно найти самую длинную общую подстроку длиной не менее 4 символов в 2 входных строках, я бы предложилPython подход:
Давайте скажем, входной файл был немного «сложным» и имел следующие строки:
1023q 023q023q
v0adc 20adc0adc
s123456 123456
eabcde cabcdefg
08tgdf 90alkhg
Чтобы найти самую длинную общую подстроку, мы будем использовать классSequenceMatcherиз модуляdifflib .
find_common_lines.py
скрипт:
import re
from difflib import SequenceMatcher
with open('filename', 'r') as fh:
for l in fh.read().splitlines():
items = re.findall(r'\S+', l.strip()) # getting 2 comparable strings
m = SequenceMatcher(None, items[0], items[1]).find_longest_match(0, len(items[0]), 0, len(items[1]))
if m.size >= 4:
print(l)
Использование(у вас может быть другая версия python3.x, текущий случай был протестирован на python3.5 ):
python3.5 find_common_lines.py
Вывод:
1023q 023q023q
v0adc 20adc0adc
s123456 123456
eabcde cabcdefg
awk решение:
Предполагая тестовый фрагмент из файла batch_1.catalog.tags.tsv
:
0 1 6 gi|586799556|ref|NW_006530744.1| 141 + consensus 0 1_33,14_43 CGGGCGGTGGTGGCGCACGCCTTTAATCCCAGCACTTGGGAGGCAGAGGCAGGTGGATCTTTGTGAGTTCGAGGCCAGCCTGGGCTACCAAGTGAGCTCC 0 0 0 0
1 2 7 hi|686711556|ref|NW_006530744.2| 141 + consensus 0 1_33,14_43 CGGGCGGTGGTGGCGCACGCCTTTAATCCCAGCACTTGGGAGGCAGAGGCAGGTGGATCTTTGTGAGTTCGAGGCCAGCCTGGGCTACCAAGTGAGCTCC 1 1 0 1
2 2 8 hi|686711556|ref|NW_006530744.2| 141 + consensus 0 1_33,14_43 CGGGCGGTGGTGGCGCACGCCTTTAATCCCAGCACTTGGGAGGCAGAGGCAGGTGGATCTTTGTGAGTTCGAGGCCAGCCTGGGCTACCAAGTGAGCTCC 1 1 1 1
3 3 9 th|776711556|ref|NW_006530744.2| 141 + consensus 1 1_33,14_43 CGGGCGGTGGTGGCGCACGCCTTTAATCCCAGCACTTGGGAGGCAGAGGCAGGTGGATCTTTGTGAGTTCGAGGCCAGCCTGGGCTACCAAGTGAGCTCC 1 0 1 1
И тестовый фрагмент из whitelight.txt
файл:
6
7
9
Команда:
awk 'NR==FNR{ a[$0]++; next }{ if ($3 in a) {
$0=">"$3 FS $4 FS $5 FS $6 FS $11 FS $12 FS $13 FS $14 RS $10; print}}' whitelist.txt batch_1.catalog.tags.tsv > cat.fa
Final cat.fa
содержимое:
>6 gi|586799556|ref|NW_006530744.1| 141 + 0 0 0 0
CGGGCGGTGGTGGCGCACGCCTTTAATCCCAGCACTTGGGAGGCAGAGGCAGGTGGATCTTTGTGAGTTCGAGGCCAGCCTGGGCTACCAAGTGAGCTCC
>7 hi|686711556|ref|NW_006530744.2| 141 + 1 1 0 1
CGGGCGGTGGTGGCGCACGCCTTTAATCCCAGCACTTGGGAGGCAGAGGCAGGTGGATCTTTGTGAGTTCGAGGCCAGCCTGGGCTACCAAGTGAGCTCC
>9 th|776711556|ref|NW_006530744.2| 141 + 1 0 1 1
CGGGCGGTGGTGGCGCACGCCTTTAATCCCAGCACTTGGGAGGCAGAGGCAGGTGGATCTTTGTGAGTTCGAGGCCAGCCTGGGCTACCAAGTGAGCTCC
Details :
NR==FNR
- выполнить действие для первого файла, т.е. whitelight.txt
a[$0]++;
- накопление чисел из файла whitelight.txt
if ($3 в a)
— разрешает действие, если значение 3-го столбца из 2-го файла совпадает с любым из накопленных чисел
RS
— разделитель записей awk, по умолчанию используется символ новой строки
perl -F'\t+' -lane '
@ARGV and $h{$F[0]}++,next;
print ">", join("\t", @F[2..5,-4..-1]), $\, $F[9] if exists $h{$F[2]};
' whitelist.txt batch_1.catalog.tags.tsv
Предположим, что ваш файл разделен TAB -.
Обратите внимание, что если в вашем файле могут быть окончания строк windows или mac, разумно сначала преобразовать их в окончания строк unix ("\n" )с помощью утилит dos2unix и т. д. Потому что много раз это было видно, что предоставленный код не работает в конце OP по подобным причинам.
Perl
обрабатывает первый аргумент (, в данном случае whitelight.txt
, тогда @ARGV содержит batch_1.catalog.tsv
файл, т. е. @ARGV = 1 => @ARGV оценивается как ИСТИНА в логическом контексте.. @ARGV and $h{$F[0]}++,next
следует интерпретировать как :, когда мы обрабатываем файл белого света, затем добавляем первое поле($F[0]
)этого файла к хешу %h
и сразу переходим к следующей строке. $F[2]
является ключом в хэше %h
. OFS
для печати —NULL
)">"
, $F[2]
означает, что 3-му полю предшествует>
@F[3..5]
будут разделены и объединены с помощью TAB. @F[-4..-1]
будут разделены и объединены с помощью TAB.$F[9]
будет предшествовать новая строка, которая обеспечивается $\
= ORS
= \n
из-за опции Perl
-l
.