Подстановка переменных окружения в sed
если я запускаю эти команды из скрипта:
#my.sh
PWD=bla
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
xxx
bla
это нормально.
но, если я запускаю:
#my.sh
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
$ sed: -e expression #1, char 8: Unknown option to `s'
Я читал в учебниках, что для замены переменных среды из оболочки вам нужно остановиться, а "out quote"$varname часть, чтобы она не была заменена напрямую, что я и сделал, и что работает только в том случае, если переменная определена непосредственно перед этим.
как я могу заставить sed распознать $var как переменная окружения, как она есть определяется в оболочке?
10 ответов:
ваши два примера выглядят одинаково, что затрудняет диагностику проблем. Потенциальные проблемы:
вам могут понадобиться двойные кавычки, как в
sed 's/xxx/'"$PWD"'/'
$PWDможет содержать косую черту, в этом случае вам нужно найти символ не содержится в$PWDиспользовать в качестве разделителя.прибить оба вопроса сразу, возможно
sed 's@xxx@'"$PWD"'@'
в дополнение к ответу Нормана Рэмси я хотел бы добавить, что вы можете дважды процитировать всю строку (что может сделать оператор более читаемым и менее подверженным ошибкам).
поэтому, если вы хотите найти 'foo' и заменить его содержимым $BAR, вы можете заключить команду sed в двойные кавычки.
sed 's/foo/$BAR/g' sed "s/foo/$BAR/g"в первом $BAR не будет правильно расширяться, а во втором $BAR будет правильно расширяться.
еще один простой вариант:
С
$PWDобычно содержит косую черту/используйте|вместо/для заявления sed:sed -e "s|xxx|$PWD|"
С вашим вопросом редактирования, я вижу вашу проблему. Допустим, текущий каталог
/home/yourname... в этом случае ваша команда ниже:sed 's/xxx/'$PWD'/'будет расширен до
sed `s/xxx//home/yourname//, который не является действительным. Вам нужно поставить
\символ перед каждой/в вашем $PWD, если вы хотите это сделать.
VAR=8675309 echo "abcde:jhdfj$jhbsfiy/.hghi$jh:12345:dgve::" |\ sed 's/:[0-9]*:/:'$VAR':/1'где VAR содержит то, что вы хотите заменить поле на
на самом деле, самое простое (по крайней мере, в gnu sed) - использовать другой разделитель для команды sed substitution (s). Поэтому вместо того, чтобы s/pattern/'$mypath'/ расширяться до s/pattern//my/path/, что, конечно же, запутает команду s, используйте s!узор!'$mypath'! который будет расширен до s!узор!/мой/путь! Я использовал взрыв (!) символ (или использовать все, что вам нравится), который избегает обычного, но-не-означает-ваш-единственный-выбор косой черты в качестве разделителя.
плохой способ: поменять разделитель
sed 's/xxx/'"$PWD"'/' sed 's:xxx:'"$PWD"':' sed 's@xxx@'"$PWD"'@'может быть, это не окончательный ответ,
вы не можете знать, какой символ будет происходить в
$PWD,/:или@.хороший способ заменить специальный символ в
$PWD.хороший способ: escape-разделитель
например:
использовать
/разделительecho ${url//\//\/} x.com:80\/aa\/bb\/aa.js echo ${url//\//\/} x.com:80/aa/bb/aa.js echo "${url//\//\/}" x.com:80\/aa\/bb\/aa.js echo $tmp | sed "s/URL/${url//\//\/}/" <a href="x.com:80/aa/bb/aa.js">URL</a> echo $tmp | sed "s/URL/${url//\//\/}/" <a href="x.com:80/aa/bb/aa.js">URL</a>или
использовать
:как разделитель (подробнее читаемый чем/)echo ${url//:/\:} x.com:80/aa/bb/aa.js echo "${url//:/\:}" x.com\:80/aa/bb/aa.js echo $tmp | sed "s:URL:${url//:/\:}:g" <a href="x.com:80/aa/bb/aa.js">x.com:80/aa/bb/aa.js</a>
работа с переменными в sed
[root@gislab00207 ldom]# echo domainname: None > /tmp/1.txt [root@gislab00207 ldom]# cat /tmp/1.txt domainname: None [root@gislab00207 ldom]# echo ${DOMAIN_NAME} dcsw-79-98vm.us.oracle.com [root@gislab00207 ldom]# cat /tmp/1.txt | sed -e 's/domainname: None/domainname: ${DOMAIN_NAME}/g' --- Below is the result -- very funny. domainname: ${DOMAIN_NAME} --- You need to single quote your variable like this ... [root@gislab00207 ldom]# cat /tmp/1.txt | sed -e 's/domainname: None/domainname: '${DOMAIN_NAME}'/g' --- The right result is below domainname: dcsw-79-98vm.us.oracle.com
у меня была аналогичная проблема, у меня был список, и я должен построить SQL-скрипт на основе шаблона (который содержал
@INPUT@как элемент заменить):for i in LIST do awk "sub(/\@INPUT\@/,\"${i}\");" template.sql >> output done
Comments