Может быть, есть способ получить перекрывающиеся совпадения с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
.
Я думаю, вы могли бы просто сделать это вручную...
Самое интересное — это различные форматы. Вот функции для Bash для создания сообщений в стиле RFC 5424 и RFC 3164 . Форматы %06N
и %:z
в метке времени первого могут потребовать даты GNU, я не уверен.
#!/bin/bash
# print RFC 5424 syslog message, without structured data,
# somewhat like 'logger -i --rfc5424=notq', e.g.
# <13>1 2021-10-28T14:48:10.613772+03:00 myhost ilkkachu 20415 - - a problem happened
# format is
# <prio>version date host tag pid - - message
lognew() {
local facility="${log_facility-5}" # default 'user'
local severity="$1"
shift
local prio=$(( facility*8 + severity ))
local version=1
local date=$(date +"%Y-%m-%dT%H:%M:%S.%06N%:z")
local tag="${log_tag-$USER}" # default to username
local pid="$$"
local IFS=" "
local message="$*"
printf "<%d>%d %s %s %s %d - - %s\n" "$prio" "$version" "$date" "$HOSTNAME" "$tag" "$pid" "$message"
}
# print RFC 3164 syslog message,
# somewhat like 'logger -i --rfc3164'
# <13>Oct 28 14:49:13 myhost ilkkachu[20418]: another problem happened
# format:
# <prio>date host tag[pid]: message
logold() {
local facility="${log_facility-5}" # default 'user'
local severity="$1"
shift
local prio=$(( facility*8 + severity ))
local date=$(LC_ALL=C date +"%b %_d %H:%M:%S")
local tag="${log_tag-$USER}" # default to username
local pid="$$"
local IFS=" "
local message="$*"
printf "<%d>%s %s %s[%d]: %s\n" "$prio" "$date" "$HOSTNAME" "$tag" "$pid" "$message"
}
log_facility=1 # user
log_tag="test"
# 6 = info
lognew 6 testing messaging
# 4 = warning
logold 4 obsolete message format
Напечатанный PID соответствует скрипту, а вывод примерно такой:
<14>1 2021-10-28T15:06:17.413125+03:00 myhost test 20499 - - testing messaging
<12>Oct 28 15:06:17 myhost test[20499]: obsolete message format