В моем скрипте bash у меня есть внешняя (полученная от пользователя) строка, которую я должен использовать в шаблоне sed.
REPLACE="<funny characters here>"
sed "s/KEYWORD/$REPLACE/g"
Как я могу избежать $REPLACE
строки, чтобы она была безопасно принята sed
как буквальная замена?
ПРИМЕЧАНИЕ. Это KEYWORD
немая подстрока без совпадений и т. Д. Она не предоставляется пользователем.
outputvar="${inputvar//"$txt2replace"/"$txt2replacewith"}".
Ответы:
Предупреждение : это не учитывает переводы строки. Для более подробного ответа см. Этот SO-вопрос . (Спасибо, Эд Мортон и Никлас Питер)
Обратите внимание, что избегать всего - плохая идея. SED потребность много символов , чтобы быть экранированы , чтобы получить свой особый смысл. Например, если вы укажете цифру в строке замены, она превратится в обратную ссылку.
Как сказал Бен Бланк, в заменяющей строке необходимо экранировать только три символа (экранирование, косая черта для конца оператора и & для замены всего):
Если вам когда-либо понадобится экранировать
KEYWORD
строку, вам понадобится следующее:И может быть использован:
Помните, что если вы используете символ, отличный от
/
разделителя, вам необходимо заменить косую черту в приведенных выше выражениях на используемый вами символ. См. Комментарий PeterJCLaw для объяснения.Отредактировано: из-за некоторых угловых случаев, ранее не учтенных, вышеприведенные команды менялись несколько раз. Проверьте историю изменений для деталей.
источник
KEYWORD
в GNU sed есть еще 2 символа^
,$
не упомянутые выше:s/[]\/$*.^|[]/\\&/g
A='foo"bar' echo $A | sed s/$A/baz/
в bash. Двойные кавычки обрабатываются так же, как 'foo' и 'bar' вокруг негоКоманда sed позволяет использовать другие символы вместо
/
разделителя:Двойные кавычки не проблема.
источник
.
что в противном случае имеет особое значение. Я отредактировал твой ответ.sed '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file
с,sed '|CLIENTSCRIPT="foo"|a CLIENTSCRIPT2="hello"' file
и это не делает то же самое.s
команда (как в замене) sed позволяет вам использовать другие символы вместо / в качестве разделителя. Кроме того, это будет ответом на то, как использовать sed в URL с косой чертой. Он не отвечает на вопрос OP, как избежать строки, введенной пользователем, которая может содержать /, \, но также #, если вы решите использовать это. И, кроме того, URI тоже может содержать #Единственными тремя литеральными символами, которые специально обрабатываются в предложении замены, являются
/
(чтобы закрыть предложение),\
(чтобы избежать символов, обратная ссылка и т. Д.) И&
(чтобы включить совпадение в замену). Поэтому все, что вам нужно сделать, это экранировать эти три символа:Пример:
источник
Основываясь на регулярных выражениях Pianosaurus, я создал функцию bash, которая экранирует как ключевое слово, так и замену.
Вот как вы используете это:
источник
man echo
), Заставляя канал работать неожиданно, когда ваш аргумент$1
начинается с тире. Вместо этого вы можете начать свою трубу сprintf '%s\n' "$1"
.Уже поздно отвечать ... но есть гораздо более простой способ сделать это. Просто измените разделитель (т. Е. Символ, который разделяет поля). Так что вместо
s/foo/bar/
тебя пишиs|bar|foo
.И вот простой способ сделать это:
Результирующий вывод лишен этого неприятного предложения DEFINER.
источник
&
и `` все еще должен быть экранирован, как и разделитель, какой бы ни был выбран.$
в строке, которая должна быть изменена, и сохранить значение$
в строке замены. скажем, я хочу изменить$XXX
значение переменной$YYY
,sed -i "s|\$XXX|$YYY|g" file
работает отлично.Оказывается, вы задаете не тот вопрос. Я тоже задал не тот вопрос. Причина, по которой это неправильно, - начало первого предложения: «В моем сценарии bash ...».
У меня был тот же вопрос и я сделал ту же ошибку. Если вы используете bash, вам не нужно использовать sed для замены строк (и гораздо удобнее использовать функцию замены, встроенную в bash).
Вместо чего-то вроде, например:
Вы можете использовать исключительно функции bash:
источник
$A
и$B
не цитируется, но это не так. Кавычки внутри${}
не совпадают с кавычками снаружи.var='has space'
) -OUTPUT=${INPUT//"$A"/"$B"}
это безопасно.Используйте awk - это чище:
источник
awk
том, что он не имеет ничего подобногоsed -i
, что очень удобно в 99% случаев.Вот пример AWK, который я использовал некоторое время назад. Это AWK, который печатает новые AWKS. AWK и SED схожи, это может быть хорошим шаблоном.
Это выглядит чрезмерно, но каким-то образом эта комбинация кавычек работает так, чтобы печатать как литералы Тогда, если я правильно помню, переменные просто заключены в такие кавычки: «$ 1». Попробуйте, дайте мне знать, как это работает с SED.
источник
У меня есть улучшение по сравнению с функцией sedeasy, которая ломается с помощью специальных символов, таких как tab.
Так что же отличается?
$1
и$2
заключенные в кавычки, чтобы избежать расширения оболочки и сохранить символы табуляции или двойные пробелы.Дополнительный трубопровод
| sed -e 's:\t:\\t:g'
(мне нравится:
как токен), который превращает вкладку в\t
.источник
Это коды перехода, которые я нашел:
источник
не забывайте все удовольствие, которое происходит с ограничением оболочки вокруг "и"
так (в кш)
источник
Если вы просто хотите заменить значение переменной в команде sed, просто удалите Пример:
источник
Если случается, что вы генерируете случайный пароль для передачи
sed
вместо шаблона, то вы должны быть осторожны с тем, какой набор символов в случайной строке. Если вы выберете пароль, созданный путем кодирования значения в виде base64, то будет присутствовать только символ, который возможен в base64 и также является специальным символом вsed
шаблоне замены. Этот символ "/", и его легко удалить из пароля, который вы генерируете:источник
Более простой способ сделать это - просто построить строку перед использованием и использовать ее в качестве параметра для
sed
источник
REPLACE=/
даетsed: -e expression #1, char 12: unknown option to `s'