sedAPI примитивен - и это по замыслу. По крайней мере, он оставался примитивным по замыслу - не мог сказать, был ли он примитивно разработан в начале. В большинстве случаев написание sedсценария, который при запуске выдаст другой sedсценарий , действительно прост. sedочень часто применяется таким образом макропроцессорами, такими как m4и / или make.
(Ниже приводится весьма гипотетический вариант использования: это проблема, разработанная для решения проблемы. Если вам кажется, что это растягивается, то, вероятно, это так, но это не обязательно делает ее менее обоснованной.)
Рассмотрим следующий входной файл:
cat <<"" >./infile
camel
cat dog camel
dog cat
switch
upper
lower
Если бы мы хотели написать sedскрипт, который добавлял бы слово- case к хвосту каждого подходящего слова в указанном выше входном файле, только если его можно было найти в строке в соответствующем контексте , и мы хотели бы сделать это максимально эффективно ( как должно быть нашей целью, например, во время операции компиляции), тогда мы должны предпочесть избегать применения /регулярных выражений /в максимально возможной степени.
Одна вещь, которую мы могли бы сделать, это предварительно отредактировать файл в нашей системе прямо сейчас и никогда не вызывать его sedво время компиляции. Но если какое-либо из этих слов в файле должно или не должно быть включено на основе локальных настроек и / или параметров времени компиляции, то это, вероятно, не будет желательной альтернативой.
Еще одна вещь, которую мы могли бы сделать, это обработать файл сейчас с помощью регулярных выражений. Мы можем создать - и включить в нашу компиляцию - sedсценарий, который может применять изменения в соответствии с номером строки - который обычно является гораздо более эффективным маршрутом в долгосрочной перспективе.
Например:
n=$(printf '\\\n\t')
grep -En 'camel|upper|lower' <infile |
sed " 1i${n%?}#!/usr/heirloom/bin/posix2001/sed -nf
s/[^:]*/:&$n&!n;&!b&$n&/;s/://2;\$a${n%?}q"'
s/ *cat/!/g;s/ *dog/!/g
s| *\([cul][^ ]*\).*|s/.*/\1-case/p|'
... который записывает вывод в виде sedскрипта и который выглядит как ...
#!/usr/heirloom/bin/posix2001/sed -nf
:1
1!n;1!b1
1s/.*/camel-case/p
:2
2!n;2!b2
2!!s/.*/camel-case/p
:5
5!n;5!b5
5s/.*/upper-case/p
:6
6!n;6!b6
6s/.*/lower-case/p
q
Когда этот вывод сохраняется в исполняемом текстовом файле на моем компьютере с именем ./bang.sedи запускается как ./bang.sed ./infile, вывод:
camel-case
upper-case
lower-case
Теперь вы можете спросить меня ... Зачем мне это делать? Почему бы мне не просто grepспички якоря ? Кто использует верблюжий чемодан? И на каждый вопрос, который я мог только ответить, я понятия не имею ... потому что я не знаю. До прочтения этого вопроса я никогда лично не замечал мульти! требование разбора в спецификации - я думаю, что это довольно аккуратный улов.
Мульти-! вещь сделал сразу имеет смысл для меня, хотя - большая часть sedспецификации ориентирована просто разобраны и просто сгенерированных sed сценариев. Вы, вероятно, найдете требуемые \nразделители ewline для [wr:bt{]большего смысла в этом контексте, и если вы будете помнить об этой идее, вы могли бы лучше понять некоторые другие аспекты спецификации - (например, :не принимать адреса и qотказываться от принять больше, чем 1) .
В приведенном выше примере я выписать определенную форму sedскрипт , который может только когда - либо будет читать один раз. Если вы внимательно посмотрите на него, вы можете заметить, что при sedчтении файла редактирования он переходит от одного блока команд к следующему - он никогда не отходит и не завершает свой скрипт редактирования до тех пор, пока он полностью не завершит свой файл редактирования.
Я считаю, что мульти! адреса могут быть более полезными в этом контексте, чем в некоторых других, но, честно говоря, я не могу вспомнить ни одного случая, в котором я мог бы использовать его очень хорошо - и мне sedэто очень нравится. Я также думаю, что стоит отметить, что GNU / BSD sedоба не справляются с этим так, как указано - это, вероятно, не тот аспект спецификации, который пользуется большим спросом, и поэтому, если реализация игнорирует его, я очень серьезно сомневаюсь, что их баги @ box будут страдать. ужасно в результате.
Тем не менее, неспособность обработать это, как указано, является ошибкой для любой реализации, которая претендует на соответствие, и поэтому я думаю, что здесь требуется отсылка электронной почты в соответствующие поля для разработчиков, и я собираюсь сделать это, если вы этого не сделаете.
!действует как переключатель,/pattern/!!такой же , как/pattern/и/pattern/!!!тот же/pattern/!. На FreeBSD несколько!одинаковы.