У меня есть набор замен sed в скрипте bash, и я получаю сообщение об ошибке о неопределенной команде `s '. Вот как выглядит строка sed:
sed -n -e "s/TMPFOO1/$FOO1/" -e "s/TMPFOO2/$FOO2/" -e "s/TMPFOO3/$FOO3/" -e "s/TMPFOO4/$FOO4/" -e "s/TMPFOO5/$FOO5/" /home/foo/template > /home/foo/template/finishedresult
По какой-то причине bash это не нравится, и я получаю сообщение об ошибке
sed: -e expression #4, char 69: unterminated `s' command
Что мне здесь не хватает? Как я могу SED ввести переменную? Мне кажется, что все они уничтожены.
shell-script
text-processing
sed
Майк Б
источник
источник
Ответы:
Вы не можете безопасно интерполировать переменную в команде sed, потому что подстановка выполняется оболочкой, а не sed. Значение переменной становится синтаксисом sed. Например,
"s/TMPFOO1/$FOO1/"
если$FOO1
в строке содержится символ новой строки, это приведет к синтаксической ошибке, подобной той, которую вы наблюдали. Если$FOO1
содержит a/
, это завершаетs
команду и может вызвать ошибку или может привести к выполнению других команд (если то, что/
происходит после , является допустимым синтаксисом sed).Несмотря на то, что вы можете выполнить первый проход подстановки,
FOO1
чтобы заключить в кавычки его специальные символы для включения в эту команду sed, использовать awk намного проще. У Awk есть понятие переменной и синтаксис командной строки для установки начального значения переменной.источник
-v
должен предшествовать каждому объявлению переменной.Скорее всего, одна из ваших
$FOO
переменных содержит специальные символы, которые интерпретируютсяsed
.У меня есть другая версия,
sed
которая генерирует другие сообщения об ошибках, но вот пример похожей проблемы:В этом случае
$VAR
содержит символ, который интерпретируетсяsed
как завершающий слеш.источник
Как уже упоминали другие, это зависит от содержимого ваших переменных FOO *. В вашем случае использование
sed
- неправильный выбор, потому что он, вероятно, содержит некоторые специальные символы.Взгляните на эту ссылку и посмотрите функцию
gsub_literal
Так как
gsub_literal
читает из stdin и пишет в stdout, использование будет:gsub_literal "$search" "$replace" < /home/foo/template > /home/foo/template/finishedresult
Пример вывода:
источник
Проблема была решена для меня путем пробной обратной косой черты в
sed 's/.../.../g'
команде. Эта командадал мне это сообщение об ошибке
когда он был выполнен как часть скрипта c-shell, и он делал это только с последней версией
sed
, а не со старой версией. (Странно, эта же команда отлично работает, когда она дается в командной строке (в tc-shell)).Проблема со сценарием c-shell была исправлена путем добавления
ä
символа обратной косой черты:источник