SED замена для переменной
У меня есть файл с именем check.txt, который имеет следующее содержимое:
$ cat check.txt
~/bin/tibemsadmin -server $URL-user $USER -password $PASWRD
$
У меня есть основной сценарий, где значения $URL, $USER, $PASWRD получены из основного сценария. Я хочу использовать утилиту SED для замены $URL, $USER, $PASWRD на фактические значения в файле check.txt.
Я пытаюсь так, но это не удается.
emsurl=tcp://myserver:3243
emsuser=test
emspasswd=new
sed s/$URL/${emsurl}/g check.txt >> check_new.txt
sed s/$USER/${emsuser}/g check.txt_new.txt >> check_new_1.txt
sed s/PASWRD/${emspasswd}/g check_new_1.txt >> final.txt
Мой вывод final.txt желателен, как показано ниже:
~/bin/tibemsadmin -server tcp://myserver:3243 -user test -password new
Не могли бы вы мне помочь?
4 ответа
Вы должны быть довольно осторожны с использованием цитат. Вам также необходимо научиться выполнять несколько операций за один проход и / или как использовать каналы.
emsurl=tcp://myserver:3243
emsuser=test
emspasswd=new
sed -e "s%\$URL%${emsurl}%g" \
-e "s%\$USER%${emsuser}%g" \
-e "s%\$PASWRD%${emspasswd}%g" check.txt >final.txt
Ваша проблема в том, что оболочка расширила '$URL' в вашей командной строке (вероятно, до нуля), что означает, что sed
должен увидеть что-то другое, чем вы хотели. Избегая $
с \
, sed
получает возможность увидеть то, что вы намеревались.
Обратите внимание, что я изначально использовал /
в качестве разделителя в замещающих операциях; однако, как справедливо отмечает DarkDust, это не сработает, поскольку в URL-адресах есть косые черты. Мой нормальный запасной персонаж %
- как сейчас показано - но это может появляться в некоторых URL-адресах и может не подходить. Я бы, вероятно, использовал контрольный символ, такой как control-A, если бы мне пришлось беспокоиться об этом - или я использовал бы Perl, который мог бы играть без запутывания.
Вы также можете объединить три отдельных -e
выражения в одно с заменой их точкой с запятой. Однако я предпочитаю четкость трех операций, четко разделенных.
Вы можете использовать немного другой подход, изменив свой основной скрипт следующим образом:
export URL="tcp://myserver:3243"
export USER=test
export PASWRD=new
. ./check.txt
Это устанавливает переменные и затем запускает check.txt в контексте вашего основного скрипта
Хотя вы не говорите, что не получается, я думаю, я вижу проблемы.
Я предлагаю вам сделать это:
sed "s|\$URL|${emsurl}|g"
То есть первый $
нужно избежать, потому что вы хотите буквально. Тогда вместо /
Я предлагаю вам использовать |
(труба) как разделитель, так как он не используется в ваших строках. Наконец, используйте "
чтобы содержимое интерпретировалось оболочкой как строка.
Затем вы можете передать все вместе, чтобы не нуждаться во временных файлах:
sed "s|\$URL|${emsurl}|g" | sed "s|\$USER|${emsuser}|g" | sed "s|\$PASSWRD|${emspasswd}|g"
Подстановка переменной должна быть вне выражения sed, а '$' должно быть экранировано; в вашем случае что-то вроде этого:
sed -e 's/\$URL/'$emsurl'/g' -e 's/\$USER/'$emsuser'/g' -e 's/\$PASSWORD/'$emaspasswd'/g'
В любом случае, на вашем месте я бы не использовал $ для сопоставления заполнителей в файле шаблона, потому что это вызывает путаницу с переменными BASH, вместо этого используйте другой шаблон (например, @URL@).