Поиск двух паттернов в строке и удаление паттернов и последовательности между ними

Используется sedнапример:

$ echo 'version: 1.8.0.110' | sed 's/\./-/3'
version: 1.8.0-110

Пояснение:

sed s/search/replace/xищет строку и заменяет вторую. xопределяет, какое вхождение заменить -здесь 3-м. Часто gиспользуется вместо xдля обозначения всех вхождений.

Здесь мы хотим заменить точку ., но это специальный символ регулярного выражения sed, ожидаемый в термине search. Поэтому мы используем обратную косую черту от .до \., чтобы указать литерал ..

Поскольку мы используем здесь специальные символы в аргументе sed(, обратную косую черту\)нам нужно поместить весь аргумент в одинарные кавычки ''. Многие люди всегда используют здесь кавычки, чтобы не столкнуться с проблемами при использовании символов, которые могут быть специфическими для оболочки (, например пробел).

0
18.11.2021, 13:13
4 ответа

Если у вас есть только одно вхождение последовательности BBBB*,вы можете указать sedудалить только первый BBBB, которому предшествует другой символ.

sed 's/^ABCD.*[^B]BBBB//'

Если последовательность BBBBначинается только один раз в каждой строке, это должно сработать.

Обратите внимание, что это не будет работать со строками типа:

ABCDEBBBBBFBBBBBXYZ

, потому что это два вхождения BBBB, которым предшествует не -B, и жадный алгоритм также поймает второе.

1
18.11.2021, 14:06

Сделать то, что вы просили для(remove everything starting with the ABCD up to, and including, the first occurence of 4 consecutive Bs.)с любым awk, было бы:

$ awk -v beg='ABCD' -v end='BBBB' '
    { gsub(end,"\n") }
    match($0,beg"[^\n]+\n") { $0=substr($0,1,RSTART-1) substr($0,RSTART+RLENGTH) }
    { gsub(/\n/,end) }
1' file
BBBBBBBBBBBBBBBBBBBBBXYZ
BBBBBBBBBBBBBBBBBBXYZ
BBBBBBBBBBBBBBBBBBBBXYZ

Это работает независимо от того, стоит ли буква ABCD первой в строке или перед ней может стоять BBBB и т. д.:

$ echo 'xyz BBBB foo ABCD bar BBBB etc BBBB anon' |
    awk -v beg='ABCD' -v end='BBBB' '{gsub(end,"\n")} match($0,beg"[^\n]+\n"){$0=substr($0,1,RSTART-1) substr($0,RSTART+RLENGTH)} {gsub(/\n/,end)} 1'
xyz BBBB foo  etc BBBB anon
1
18.11.2021, 14:07

Задачу можно разбить на два этапа. Ставим отметку и потом удаляем:

sed '/ABC/s/B\{4\}/&\n/;s/ABC.*\n//' file

\n-отметка

Чтобы избежать ложных случаев, когда шаблон BBBBстоит перед шаблоном ABC, можно добавить еще одну команду, которая снимет ложную отметку:

sed 's/B\{4\}/&\n/;s/ABC.*\n//;s/\n//' file
1
18.11.2021, 14:29

Использование Raku (, ранее известного как Perl _6)

raku -pe 's/^^ ABCD.*? B**4 //;'

Пример ввода:

ABCDABCBCBBBCBCDDBBBBBBBBBBBBBBBBBBBBBBBBBXYZ
ABCDCCCBCCBBBBBBBBBBBBBBBBBBBBBBXYZ
ABCDACDCDCCCCBBBBBBBBBBBBBBBBBBBBBBBBXYZ

Пример вывода:

BBBBBBBBBBBBBBBBBBBBBXYZ
BBBBBBBBBBBBBBBBBBXYZ
BBBBBBBBBBBBBBBBBBBBXYZ

Выше приведено решение, написанное на Raku, члене семейства языков программирования Perl -. Raku включает сложное обновление хорошо зарекомендовавшего себя -механизма PCRE. Тем не менее, в приведенном выше коде используется знакомый оператор s///в сочетании с флагами-pe(auto -построчной печати ).

Для описанной проблемы решение так же просто, как преобразование «жадного» .*регулярного выражения в «бережливое» .*?регулярное выражение. Простого включения ?достаточно, чтобы Раку знал, что нужно остановиться в соответствующем месте, ближайшем к левому-концу последовательного-Bпрогона (регулярное выражение B**4говорит Раку искать 4 -последовательных Bс ).

Это самое простое решение. Однако, если вам нужна помощь в визуализации того, что удаляется, просто переключитесь на -neне -построчный флаг автопечати (s )в сочетании сS///(недеструктивной подстановкой -)илиm/…/(соответствуют операторам ):

$ raku -pe 's/^^ ABCD.*? B**4 //;' file
BBBBBBBBBBBBBBBBBBBBBXYZ
BBBBBBBBBBBBBBBBBBXYZ
BBBBBBBBBBBBBBBBBBBBXYZ
$ raku -ne 'put S/^^ ABCD.*? B**4 //;' file
BBBBBBBBBBBBBBBBBBBBBXYZ
BBBBBBBBBBBBBBBBBBXYZ
BBBBBBBBBBBBBBBBBBBBXYZ
$ raku -ne 'put s/^^ ABCD.*? B**4 //;' file
ABCDABCBCBBBCBCDDBBBB
ABCDCCCBCCBBBB
ABCDACDCDCCCCBBBB
$ raku -ne 'm/^^ ABCD.*? B**4 /.put;' file
ABCDABCBCBBBCBCDDBBBB
ABCDCCCBCCBBBB
ABCDACDCDCCCCBBBB

https://docs.raku.org/language/regexes
https://raku.org

1
18.11.2021, 23:47

Теги

Похожие вопросы