Это (наряду со многими другими вещами PageXXX ), определенными в include/linux/page-flags.h
, но определение затемнено использованием макросов. См. макрос TESTPAGEFLAG
в приведенном выше файле.
В частности, это определение макроса TESTPAGEFLAG:
#define TESTPAGEFLAG(uname, lname, policy) \
static __always_inline int Page##uname(struct page *page) \
{ return test_bit(PG_##lname, &policy(page, 0)->flags); }
в сочетании с этим вызовом TESTPAGEFLAG с параметрами обратной записи:
TESTPAGEFLAG(Writeback, writeback, PF_NO_COMPOUND)
Поскольку вам нужны перекрывающиеся строки, боюсь, ни один инструмент не может обеспечить это по умолчанию. Необходимо перебрать вход, чтобы найти все перекрывающиеся вхождения. Следующая проблема — жадный характер регулярных выражений :. Вы не найдете опережающего ATCGTA
, если можно найти ATCGTAGCTA
. Это усложняет выполнение цикла :
sed -E ':1
h;s/(.*TA).*/\1/
s/.{0,20}TA$/_&/
s/.*_//p
g;s/(.*)TA.*/\1/;t1
d
— первое решение, которое пришло мне в голову. Вывод для примера должен содержать все нужные вам последовательности:
GATGCTGCTATGCTAGATGCTA
TCGTATCGATGCTGCTATGCTA
TAGCATCGTATCGATGCTGCTA
ATCGTAGCTAGCATCGTA
ATCGTAGCTA
ATCGTA
Объяснение :Кажется, проще начать с последнего совпадения, поэтому
h
сохранить буфер в резервной области для следующего цикла s/(.*TA).*/\1/
удаляет все после последнегоTA
s/.{0,20}TA$/_&/
ставит подчеркивание в качестве маркера в начале последовательности, которую вы хотите получить s/.*_//p
удаляет все до маркера и печатает последовательность g
восстанавливает сохраненный шаблон, а s/(.*)TA.*/\1/
удаляет последний TA
и последующие, чтобы его больше нельзя было найти t1
начинается с :1
, в то время как последовательность была найдена. d
подавляет ложный вывод в конце Может быть, есть способ получить перекрывающиеся совпадения сgrep -o
(Я не знаю ни одного, даже с grep -Po
), но тем временем вы можете использоватьawk
:
echo ATCGTAGCTAGCATCGTATCGATGCTGCTATGCTAGATGCTAGT |
awk '{
i=0; for(s=$0; j = index(s,"TA"); s = substr($0, i + 1))
print ((i += j) > 20) ? substr($0, i - 20, 22) : substr($0, 1, i+1)
}'
ATCGTA
ATCGTAGCTA
ATCGTAGCTAGCATCGTA
TAGCATCGTATCGATGCTGCTA
TCGTATCGATGCTGCTATGCTA
GATGCTGCTATGCTAGATGCTA
Если вам не нужны более короткие совпадения с начала строки, упростите их до:
echo ATCGTAGCTAGCATCGTATCGATGCTGCTATGCTAGATGCTAGT |
awk '{
i=0; for(s=$0; j = index(s,"TA"); s = substr($0, i + 1))
if((i += j) > 20) print substr($0, i - 20, 22)
}'
TAGCATCGTATCGATGCTGCTA
TCGTATCGATGCTGCTATGCTA
GATGCTGCTATGCTAGATGCTA
То же самое вperl
:
echo ATCGTAGCTAGCATCGTATCGATGCTGCTATGCTAGATGCTAGT |
perl -nle 'print $-[0] > 20 ? substr $_, $-[0]-20, 22 : substr $_, 0, $+[0] while /TA/g'
ATCGTA
ATCGTAGCTA
ATCGTAGCTAGCATCGTA
TAGCATCGTATCGATGCTGCTA
TCGTATCGATGCTGCTATGCTA
GATGCTGCTATGCTAGATGCTA
echo ATCGTAGCTAGCATCGTATCGATGCTGCTATGCTAGATGCTAGT |
perl -nle 'pos() -= 21, print $1 while /(.{20}TA)/g'
TAGCATCGTATCGATGCTGCTA
TCGTATCGATGCTGCTATGCTA
GATGCTGCTATGCTAGATGCTA
При использованииmawk
(по умолчанию в Debian -, например ), версия awk
будет быстрее.
Хоть это и подходит для демонстрации sed
мастерства, любое sed
решение должно быть на много порядков медленнее, чем perl
или awk
.