Три разные sed
команды:
sed '$!N;s/"[^"]*"\n<[^>]*>/other characters /;P;D'
sed -e :n -e '$!N;s/"[^"]*"\n<[^>]*>/other characters /;tn'
sed -e :n -e '$!N;/"$/{$!bn' -e '};s/"[^"]*"\n<[^>]*>/other characters /g'
Все они s///
основаны на основной команде ubstitution:
s/"[^"]*"\n<[^>]*>/other characters /
Они также все стараются позаботиться об обработке последней строки, так как sed
s имеют тенденцию различаться по своему выводу в крайних случаях. Это значение $!
адреса, соответствующего каждой строке, которая !
не является $
последней.
Все они также используют команду N
ext, чтобы добавить следующую строку ввода к \n
пробелу шаблона после символа ewline. Любой, кто занимался sed
какое-то время, научится полагаться на \n
персонажа ewline - потому что единственный способ получить его - это явно поместить его туда.
Все три делают некоторую попытку прочитать как можно меньше входных данных, прежде чем предпринимать какие-либо действия - sed
действуют так быстро, как это возможно, и не нужно читать весь входной файл перед этим.
Хотя они делают все N
, они все три отличаются по своим методам рекурсии.
Первая команда
Первая команда использует очень простой N;P;D
цикл. Эти три команды встроены в любую POSIX-совместимую систему sed
и прекрасно дополняют друг друга.
N
- как уже упоминалось, добавляет N
строку ввода ext в шаблонное пространство после вставленного \n
разделителя ewline.
P
- как p
; он P
запечатлевает шаблонное пространство - но только до первого встречающегося \n
символа ewline. И так, с учетом следующего ввода / команды:
printf %s\\n one two | sed '$!N;P;d'
sed
P
звонит только один . Тем не менее, с ...
D
- как d
; он D
выбирает шаблонное пространство и начинает другой цикл строки. В отличие от d
, D
удаляет только до первой \n
встречной линии в шаблонном пространстве. Если после \n
символа ewline в шаблонном пространстве больше, sed
начинается следующий цикл строки с тем, что остается. Если d
в предыдущем примере было заменено на D
, например, sed
будет P
набирать как один, так и два .
Эта команда повторяется только для строк, которые не соответствуют s///
выражению ubstitution. Поскольку s///
ubstitution удаляет \n
ewline, добавленный с помощью N
, при sed
D
выборке шаблон-пространства ничего не остается .
Можно выполнить тесты для применения P
и / или D
выборочно, но есть и другие команды, которые лучше подходят для этой стратегии. Поскольку рекурсия реализована для обработки последовательных строк , которые соответствуют только части правила замены, последовательные последовательности линий , соответствующих оба конца на s///
ubstitution не работают хорошо .:
Учитывая этот вклад:
first "line"
<second>"line"
<second>"line"
<second>line and so on
... это печатает ...
first other characters "line"
<second>other characters line and so on
Это, однако, обрабатывать
first "line"
second "line"
<second>line
...просто хорошо.
Вторая команда
Эта команда очень похожа на третью. Оба используют ярлык :b
ранчо / t
est (как также продемонстрировано в ответе Джозефа Р. здесь ) и возвращаются к нему при определенных условиях.
-e :n -e
- переносимые sed
сценарии разграничивают определение :
метки либо с помощью \n
ewline, либо с помощью нового встроенного -e
оператора xecution.
:n
- определяет метку с именем n
. Это может быть возвращено в любое время с помощью bn
или tn
.
tn
- команда t
est возвращается к указанной метке (или, если она не указана , выходит из сценария для текущего цикла строки), если s///
возникла какая-либо замена, поскольку либо метка была определена, либо поскольку она в последний раз называлась t
успешной проверкой.
В этой команде рекурсия происходит для совпадающих строк. Если sed
успешно заменить шаблон с другими символами , sed
возвращается к :n
метке и пытается снова. Если s///
замена не выполняется, sed
автоматически печатается шаблонное пространство и начинается следующий цикл строки.
Это имеет тенденцию обрабатывать последовательные последовательности лучше. Там, где последний провалился, это печатает:
first other characters other characters other characters line and so on
Третья команда
Как уже упоминалось, логика здесь очень похожа на последнюю, но тест более явный.
/"$/bn
- это sed
тест. Поскольку команда b
ранчо является функцией этого адреса, sed
она b
вернется на ранчо только :n
после добавления \n
ewline, и пространство шаблона все еще заканчивается "
двойной кавычкой .
Между N
и b
как можно меньше делается - таким образом sed
можно очень быстро собрать ровно столько информации, сколько необходимо, чтобы гарантировать, что следующая строка не может соответствовать вашему правилу. В s///
ubstitution отличается здесь в том , что она использует g
ЛОБАЛЬНЫЙ флаг - и поэтому он будет делать все необходимые замены сразу. При одинаковом вводе эта команда выводит идентично последнему.
\n
заявление ewline вы делаете почему я спрашиваю. люди редко спрашивают, могут ли они сделать тоs//\n/
же самое, что и вы с GNUsed
, хотя большинство другихsed
отклонят этот побег с правой стороны. тем не менее,\n
escape будет работать слева в любом POSIX,sed
и вы можете переносить их, какy/c/\n/
будто это будет иметь тот же эффект, чтоs/c/\n/g
и не всегда так полезно.