В этом редактировании
Stéphane Chazelas POSIX исправляет (снова) мое sed
форматирование, вставляя -e
разрыв xpression и еще -e
один оператор xpression. Теперь, я мог бы просто спросить его, почему в комментариях, я полагаю, но это уже редакция № 18 для этого ответа, и почти все предыдущие были уже благодаря подобной халяве (если вы видите удаленные комментарии, вы будете знать, что Я имею в виду) . Кроме того, я думаю, что я достаточно близок к пониманию того, почему формулировать это так, чтобы это могло быть более полезным в целом. Так что надеемся ...
Как правило, я предпочитаю, чтобы мои общие sed
-e
выражения были равны единице, но я бы также предпочел соответствовать спецификации настолько близко, насколько я могу, особенно когда разница составляет не более чем a <space>
и an -e
. Но я не могу сделать это, если я не понимаю, почему я должен. Вот краткое изложение текущего состояния моего понимания:
' -e '
перерыв может переносимый стоять в течениеsed
сценария\n
перерыва ewline вsed
командной строке заявлении ... Я правда нечеткий о том, почемузакрывающей скобке в
sed
{
функции}
должен предшествовать\n
разрыв строки, как указано здесь:<right-brace>
Должен предшествовать<newline>
и может предшествовать или следовать за<blank>
персонажами.
\n
перерыв ewline аналогично требуется после любого использования ...a
,b
,c
,i
,r
,t
,w
, или:
.
Но я не совсем понимаю, как определение {
функции }
относится к !
неоператору. Единственное упоминание об операторе отрицания, которое я нахожу в спецификации:
- Функции может предшествовать один или несколько
!
символов, и в этом случае функция должна применяться, если адреса не выбирают пространство шаблона.
Значит ли это, что использование скобок !
подразумевает ? Что из команд - они также должны быть разделены перерывами? Было ли это то, что было решено, когда Стефан в последний раз POSIXified мой ответ?{
}
$!
' -e '
Я думаю, что это либо !
оператор отрицания, либо оператор b
ранчо, к которому он обращается в своем редактировании - или, возможно, это оба одновременно - но я не знаю и хотел бы этого. Если это толькоb
ранчо заявление, то я считаюd
, бы на своем месте и устранить необходимость ' -e '
перерыва, но я предпочел бы быть уверенным , прежде чем трижды рискуя POSIXified ответ. Вы можете помочь?
Я рискну все - таки , а не с какой - либо большой долей уверенности ...
b;n;:b
этого вы";n;:b"
переходите на метку, называемую в исторических и POSIX-сборках (и GNU sed не в этом отношении).:
роль - ты поехал домой несколько месяцев назад. Но я не совсем понимаю, почему втораяsed
команда была так же POSIXified .sed
меня очень неясна. Я просил разъяснения несколько раз в прошлом, но я не думаю, что это было обновлено в результате. Хорошим тестом является попытка использования инструментальной панели семейной реликвии (Solaris, взятой из оригинала и на которой в значительной степени основана спецификация POSIX).s///
учреждения должны принимать цепочку с ; , оно расплывчато вокруг команд, которые должны быть разделены новой строкой, и как они-e
могут стоять в этом случае - по крайней мере, для меня. Я еще не наткнулся на,sed
который не интерпретирует их довольно взаимозаменяемо, хотя.;
перед новой строкой - новая строка в порядке. Честно говоря, вы можете обойтись без-e
и все полностью и просто написать файл, как#!/bin/sed
с каждой командой на новой строке - или те, которые не требуют таких разделителей вместо разделителей;
. Те , которые делают требуют перевода строки , как правило , являются те , которые принимают произвольные входные -:
имена меток и команды , которые относятся к ним , какb
иt
или закрывать}
Curlies для функций, илиr
EAD иw
обряда , которые принимают имя файла арг. За ними все должно следовать\n
.Ответы:
Так что давно пора на этот вопрос был ответ, и, хотя я в конце концов интуитивно понял, как сделать это правильно почти во всех случаях некоторое время назад, я только совсем недавно сумел довольно четко конкретизировать это понимание с помощью текста в стандарте. , Там на самом деле сказано довольно просто - я просто тупо пропустил это много раз, наверное.
Соответствующие части текста находятся под заголовком ...
Редактирование команд в
sed
:Аргумент текст должен состоять из одной или нескольких строк. Каждой встроенной электронной
\n
строке в тексте должен предшествовать\
обратный слеш. Другие обратные слеши в тексте должны быть удалены, а следующий символ должен трактоваться буквально.В
r
иw
командных глаголах, иw
флаг вs
команду, возьмите дополнительный ОФАЙЛ (или wfile ) параметр, отделенный от команды глагола буквы или флага одной или более<blank>s
; реализации могут разрешить нулевое разделение как расширение.Команда глаголов, кроме
{
,a
,b
,c
,i
,r
,t
,w
,:
, и#
может сопровождаться;
точкой с запятой, опционально<blank>s
, и другой команды глагола. Однако, когдаs
командный глагол используется сw
флагом, следование за ним с другой командой таким способом приводит к неопределенным результатам....в...
Опции: Несколько
-e
и-f
опции могут быть указаны. Все команды должны быть добавлены в скрипт в указанном порядке, независимо от их происхождения.-e
script - добавить команды редактирования, заданные параметром-аргументом script, в конец скрипта команд редактирования. Сценарий вариант аргументов, имеет те же свойства, что и сценарий операнда, описанный в операнды разделе.-f
script_file - добавить команды редактирования в файле script_file в конец скрипта.И последний в ...
Операнды:
\n
строки.Таким образом, когда вы берете его полностью, имеет смысл, что любая команда, за которой необязательно следует произвольный параметр без предопределенного разделителя (в отличие,
s d sub d repl d flag
например, от него), должна быть\n
разделена на неэкранированную строку.Можно утверждать , что
;
является предопределенным разделитель , но в этом случае , используя;
любой из[aic]
команд потребовали бы , что отдельный анализатор будет включен в реализации специально для этих трех команд - отдельный, то есть от парсера , используемым для[:brw]
, например. Или же реализация бы требовать , чтобы;
также быть экранирована обратная наклонная черта в текстовом параметре и только усложняется оттуда.Полагаю, что если бы я писал код,
sed
который хотел бы быть и совместимым, и эффективным, я бы не стал писать такой отдельный анализатор, за исключением того, что, возможно,[aic]
должен генерироваться синтаксический\n
код ошибки, если сразу за ним не следует ewline. Но это простая проблема токенизации - случай с конечным разделителем, как правило, более проблематичен. Я бы просто написал это так:...и...
... будет вести себя очень схожим образом: первый создаст и запишет в файл с именем:
... а второй добавит блок текста к текущей строке на выходе, как ...
... потому что оба будут использовать один и тот же код синтаксического анализа для параметра.
А что касается
{ ... }
и$!
вопроса - ну, я был далеко там. Отдельная команда, которой предшествует адрес, - это не функция, а скорее адресная команда. Почти все команды, включая{
определение функции}
, указываются для принятия/one/
или/one/,/two/
адреса, за исключением определения#
комментария и:
метки . И адрес может быть либо номером строки, либо регулярным выражением и может быть отменен с помощью!
. Так что все ...... может сопровождаться
;
несколькими командами в соответствии со стандартом, но если для одного адреса требуется больше команд, и этот адрес не следует переоценивать после выполнения каждой команды, то должна использоваться{
функция}
, подобная следующей:... где
{
за этой же строкой не может следовать закрытие}
и что закрытие}
не может произойти, кроме как в начале строки. Но если в противном случае за содержащейся командой не должна следовать электронная\n
линия, то она также не должна быть включена в функцию. Таким образом, за всеми перечисленными вышеs///
учреждениями - и даже с закрывающей}
скобкой - переносятся;
точки с запятой и дальнейшие команды.Я продолжаю говорить об
\n
ограничителях ewline, но вопрос вместо-e
этого в выражениях xpression, я знаю. Но они на самом деле одно и то же, и ключевое отношение заключается в том, что сценарий может быть либо буквальным аргументом командной строки, либо файлом с любым из них-[ef]
, и что оба интерпретируются как текстовые файлы (которые указываются в конце\n
ewline), но ни одна из них не должна заканчиваться на\n
ewline. К этому я могу reasonbly (я надеюсь) , делают вывод , что\0NUL
разграничены аргумент подразумевает окончание\n
ewline, и , как все аргументы Призыва получить по крайней мере) на\0NUL
разделитель в любом случае, то либо должно работать нормально.Фактически, на практике, в каждом случае, кроме одного, в котором стандарт указывает
\
перевод строки с обратной косой чертой, я обнаружил, что я обнаружил ...... работать так же хорошо. И в каждом случае - опять же на практике - там, где
\n
должна быть не спасшаяся электронная линия ...... работал и для меня тоже. Единственное исключение, которое я упомянул выше, это ...
... который не работает ни для какой реализации ни в одном из моих тестов. Я вполне уверен, что это связано с требованием текстового файла и фактом, который
s///
идет с разделителем, и поэтому нет никаких причин, чтобы одно утверждение охватывало\0NUL
аргументы с разделителями.Итак, в заключение приведем краткое изложение переносимых способов написания нескольких видов
sed
команд:Для любого из
[aic]
:...или...
Для любого,
[:rwtb]
где параметр является необязательным (для всех, кроме:
), но\n
ewline разграничения не является . Обратите внимание, что у меня никогда не было причины пробовать использовать несколько параметров меток строк, как это было бы с ними[:tb]
, но чтоw
переход /r
чтение нескольких строк в параметрах файла [rw] обычно принимается без вопросовsed
s, которые я тестировал, пока встроенный\n
ewline сбежал с\
обратной косой чертой. Тем не менее, стандарт прямо не указывает, что параметры метки и файла [rw] должны анализироваться идентично тексту.параметры и не упоминает\n
ewlines относительно первых двух, за исключением того, что они разграничивают их....или...
... где
<space>
выше необязательно для[:tb]
.И последнее ...
...или...
... где любая из вышеупомянутых команд (за исключением
:
) также принимает по крайней мере один адрес и который может быть либо/
регулярным выражением,/
либо номером строки и может быть отменен с помощью!
, но если для одной оценки адреса требуется более одной команды, то Необходимо использовать фигурные скобки для разделения{
функций}
. Функция может содержать даже несколько\n
команд, разделенных ewline, но каждая из них должна быть заключена в фигурные скобки, как это было бы в противном случае.И вот как писать переносимые
sed
скрипты.источник