Три разные 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 /
Они также все стараются позаботиться об обработке последней строки, так как seds имеют тенденцию различаться по своему выводу в крайних случаях. Это значение $!адреса, соответствующего каждой строке, которая !не является $последней.
Все они также используют команду Next, чтобы добавить следующую строку ввода к \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 удаляет \newline, добавленный с помощью 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ранчо / test (как также продемонстрировано в ответе Джозефа Р. здесь ) и возвращаются к нему при определенных условиях.
-e :n -e- переносимые sedсценарии разграничивают определение :метки либо с помощью \newline, либо с помощью нового встроенного -eоператора xecution.
:n- определяет метку с именем n. Это может быть возвращено в любое время с помощью bnили tn.
tn- команда test возвращается к указанной метке (или, если она не указана , выходит из сценария для текущего цикла строки), если s///возникла какая-либо замена, поскольку либо метка была определена, либо поскольку она в последний раз называлась tуспешной проверкой.
В этой команде рекурсия происходит для совпадающих строк. Если sedуспешно заменить шаблон с другими символами , sedвозвращается к :nметке и пытается снова. Если s///замена не выполняется, sedавтоматически печатается шаблонное пространство и начинается следующий цикл строки.
Это имеет тенденцию обрабатывать последовательные последовательности лучше. Там, где последний провалился, это печатает:
first other characters other characters other characters line and so on
Третья команда
Как уже упоминалось, логика здесь очень похожа на последнюю, но тест более явный.
/"$/bn- это sedтест. Поскольку команда bранчо является функцией этого адреса, sedона bвернется на ранчо только :nпосле добавления \newline, и пространство шаблона все еще заканчивается "двойной кавычкой .
Между Nи bкак можно меньше делается - таким образом sedможно очень быстро собрать ровно столько информации, сколько необходимо, чтобы гарантировать, что следующая строка не может соответствовать вашему правилу. В s///ubstitution отличается здесь в том , что она использует gЛОБАЛЬНЫЙ флаг - и поэтому он будет делать все необходимые замены сразу. При одинаковом вводе эта команда выводит идентично последнему.
\nзаявление ewline вы делаете почему я спрашиваю. люди редко спрашивают, могут ли они сделать тоs//\n/же самое, что и вы с GNUsed, хотя большинство другихsedотклонят этот побег с правой стороны. тем не менее,\nescape будет работать слева в любом POSIX,sedи вы можете переносить их, какy/c/\n/будто это будет иметь тот же эффект, чтоs/c/\n/gи не всегда так полезно.