Intereting Posts
Что означает echo -e \ e – как побег? Обнаружение экрана и обратная передача мыши (ось x & y) kali linux Почему ядро ​​убивает мой процесс с отключением при выходе из системы? Мне нравится по умолчанию «X» образный перекрестие курсора в linux. Как заставить Debian использовать этот большой X вместо обычного курсора мыши? Какой пользователь выполняет сценарий / приложение Linux как? Thunderbird: новое уведомление по электронной почте не работает Во всяком случае, чтобы применить фильтр во время снимка btrfs subvolume? транспонировать наборы из трех строк в столбцы Процесс Weblogic просто внезапно убит на redhat linux Как получить доступ к флеш-сайту, который отклоняет мой плагин (64-разрядный)? Какой аварийный диск (аварийный CD / DVD) для восстановления данных с отказавшего жесткого диска вы бы порекомендовали для первого пользователя? Правильное использование escape-символов в файле рабочего стола Как перемещаться по xargs, где каждый скрипт использует общую переменную env Беспроводная передача, Как создать горячую точку Как заставить службу /etc/xdg/autostart/app.desktop ждать службы (systemd)?

Как вложить глобальные совпадения с sed?

Если я сделаю:

sed 's/match/replace/g' 

Я знаю, что sed заменит замену для каждого совпадения на линии. А вдруг…?

 echo "match <please dont match this?>" | sed 's/match/replace/g' 

…или…

 echo "never match unless <the match is somehow delimited?>" | sed 's/match/replace/g' 

Я знаю, что я могу использовать t est или b ranch loops для повторной обработки совпадений, но как я могу пропустить разделы строки в контексте s///g lobal match?

Дело в том, что это жадность . Он будет собирать как можно больше для каждого случая. Это может быть использовано в ваших интересах в контексте замены s///g lobal. Если вы \( group \) * совпадения с нулем или больше строки, sed будет gobobly gobble the first в каждом случае. И поэтому, если вы можете надежно разграничить соответствие / / this / | skip this | Если вы можете сделать что-то вроде этого:

 sed 's/\([^<>]*<\)*\(match *\)*\(remove *\)*/\1/g s/.\{,45\}[^ ]*/&\ /g; s/\(\n\) */\1/g ' <<INPUT Never remove any match unless <the match \ you want to remove is somehow delimited.> \ And you can remove any match <per your match \ delimiter as many times as your match occurs \ within the match delimiters.> INPUT 

ВЫВОД

 Never remove any match unless <the you want to is somehow delimited.> And you can remove any match <per your delimiter as many times as your occurs within the delimiters.> 

Входной сигнал есть одна строка, потому что оболочка избегает новых строк в этом документе на обратную косую черту. sed разделяет его на 45 символов (выдавать или принимать) и печатает его. Тем не менее, как вы можете видеть, все случаи совпадения или удаления вне границы <…> остаются, тогда как все те, которые находятся внутри, удаляются из вывода.

Это функция жадности sed , так как она применяется к совпадению * ноль или больше раз. Именно эта жадность делает невозможным выполнение замен аналогичным образом, хотя для отмены требуется только один шаг или два.

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

 printf '%s %s\n' '<321Nu0-9mber123>' \ 'String321strinG' \ '<321Nu0-9mber123>' \ 'String321strinG' | sed 's/\(<[^<>]*>\)*[0-9]*/\1!/g' 

ВЫВОД

 <321Nu0-9mber123>! !S!t!r!i!n!g!s!t!r!i!n!G! <321Nu0-9mber123>! !S!t!r!i!n!g!s!t!r!i!n!G! 

Поэтому, когда sed сопоставляет линию по глобальному шаблону, она пытается сопоставить этот шаблон столько раз, сколько может, сохраняя свою характерную жадность. Побочный эффект жадности, когда шаблон для нулей или более вхождений указан и не соответствует разделу строки, состоит в том, что он по- прежнему соответствует – он соответствует нулевой строке между байтами на части строки, в которой она не выполнялась чтобы соответствовать.

Выше видно, что строка <…> не затронута, а цифры, которые были внутри String … , не только исчезли, но и то, что sed вставил удары для каждого символа. Это отражает совпадение sed для нулевой строки каждый раз. Именно по этой причине эта методика полезна для того, чтобы она ограничивала замену спичек вместо того, чтобы делать это.

И вот как это может работать:

 printf '%s\t%s\n' '<321Nu0-9mber123>' \ 'String321strinG' \ '<321Nu0-9mber123>' \ 'String321strinG' | sed 's/[0-9]/&\n/g;s/\(<[^<>]*>\)*\n*/\1/g;y/\n/0/' 

ВЫВОД

 <302010Nu00-90mber102030> String321strinG <302010Nu00-90mber102030> String321strinG 

Это добавляет ноль к каждой цифре, которая встречается внутри < и > – это довольно простой случай, но, по правде говоря, вы можете использовать символ \n ewline таким образом, чтобы выполнять глобальные замены для любого соответствия. Основной принцип:

  1. Сделайте sed 's/match/&\n/g'
  2. Затем сделайте sed 's/\(match group\)*\n*/\1/g'
  3. Last do sed 's/match\n/replace/g'

По общему признанию, эти примеры демонстрируют только примеры с плоскими списками – < всегда предшествует > . Гнездам тоже нужно учитывать. Они сложнее – иногда намного сложнее – но, хорошо …

 sed 's/\([{}]\)\([^{}]*[{}]*\1\)*/\n<&>/g ' <<\INPUT {{{1!}{2!}{3!}}}outside!{{{4!}}{{5!}}} INPUT 

ВЫВОД

 <{{{1!}{2!}{>3! <}}}>outside! <{{{4!}}{{>5! <}}}> 

Он сериализует группы в новых линиях. Он работает, чередуя разделитель, который он сопоставляет в каждой группе соответствия, одновременно укладывая столько же одного и того же разделителя вида столько, сколько он может дважды подряд (по крайней мере дважды), а по мере того, как побочный эффект заканчивается, сравнение открывается на закрытие. Тем не менее, для простоты, все остальное предполагает, что любой читатель будет использовать аналогичные средства для подготовки ввода, а гнезда – не проблема.

По сути, оперативная идея ко всему этому является приоритетом матча. Первый пример работал, пытаясь сопоставить любую группу символов без разделителя, непосредственно предшествующих открытому разделителю, прежде чем пытаться сопоставить строки удаления. Разумеется, если первая группа будет соответствовать тогда, когда замена завершится, вся согласованная группа может быть заменена только собой – и это может затруднить замену. Удаление проще, потому что, когда вы их сопоставляете, вы просто оставляете их вне подстановки, и все в порядке.

Также sed оценивает некоторые типы шаблонов больше, чем другие. Важно понимать, что когда вы это делаете, любой определенно определенный шаблон всегда будет иметь больше веса, чем случай с нулем или больше . Поэтому, когда вы используете их для глобальных шаблонов, используйте только * или не используете их вообще – или вы можете вообще не пропускать группы.

И так вы делаете это с sed .