Si j'exécute ces commandes à partir d'un script:
#my.sh
PWD=bla
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
xxx
bla
c'est bon.
Mais si je cours:
#my.sh
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
$ sed: -e expression #1, char 8: Unknown option to `s'
J'ai lu dans des tutoriels que pour substituer des variables d'environnement à partir de Shell, vous devez vous arrêter, et "citer" la partie $varname
afin qu'elle ne soit pas substituée directement, ce que j'ai fait et qui ne fonctionne que si la variable est défini immédiatement avant.
Comment faire pour que sed puisse reconnaître un $var
en tant que variable d'environnement tel qu'il est défini dans le shell?
Vos deux exemples semblent identiques, ce qui rend les problèmes difficiles à diagnostiquer. Problèmes potentiels:
Vous aurez peut-être besoin de guillemets doubles, comme dans sed 's/xxx/'"$PWD"'/'
$PWD
peut contenir une barre oblique. Dans ce cas, vous devez rechercher un caractère non contenu dans $PWD
à utiliser comme délimiteur.
Pour résoudre les deux problèmes à la fois, peut-être
sed 's@xxx@'"$PWD"'@'
En plus de la réponse de Norman Ramsey, j'aimerais ajouter que vous pouvez doubler la chaîne entière (ce qui rendrait la déclaration plus lisible et moins sujette aux erreurs).
Donc, si vous souhaitez rechercher 'foo' et le remplacer par le contenu de $ BAR, vous pouvez inclure la commande sed entre guillemets.
sed 's/foo/$BAR/g'
sed "s/foo/$BAR/g"
Dans la première, $ BAR ne se développera pas correctement tandis que dans la deuxième $ BAR se développera correctement.
Vous pouvez utiliser d'autres caractères en plus de "/" en substitution:
sed "s#$1#$2#g" -i FILE
Une autre alternative facile:
Puisque $PWD
contient généralement une barre oblique /
, utilisez |
au lieu de /
pour l'instruction sed:
sed -e "s|xxx|$PWD|"
Avec votre question modifier, je vois votre problème. Supposons que le répertoire en cours est /home/yourname
... dans ce cas, votre commande ci-dessous:
sed 's/xxx/'$PWD'/'
sera étendu à
sed `s/xxx//home/yourname//
ce qui n'est pas valide. Vous devez mettre un caractère \
devant chaque /
dans votre $ PWD si vous voulez le faire.
sed 's/xxx/'"$PWD"'/'
sed 's:xxx:'"$PWD"':'
sed 's@xxx@'"$PWD"'@'
peut-être que ce n'est pas la réponse finale,
vous ne pouvez pas savoir quel caractère se produira dans $PWD
, /
:
OR @
.
le bon moyen est de remplacer le caractère spécial dans $PWD
.
par exemple:
utiliser /
comme délimiteur
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>
OR
utilisez :
comme délimiteur (plus lisible que /
)
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>
VAR=8675309
echo "abcde:jhdfj$jhbsfiy/.hghi$jh:12345:dgve::" |\
sed 's/:[0-9]*:/:'$VAR':/1'
où VAR contient ce que vous souhaitez remplacer par ce champ
En fait, la chose la plus simple (du moins en général) consiste à utiliser un séparateur différent pour la commande sed substitution (s). Donc, au lieu de s/pattern/'$ mypath'/en cours d’extension vers s/pattern // my/path/qui va bien sûr confondre la commande s, utilisez s! Pattern! '$ Mypath'! qui sera étendu à s! pattern!/my/path! J'ai utilisé le caractère bang (!) (Ou tout ce que vous voulez) qui évite la barre oblique habituelle, mais qui ne veut pas dire, c'est-à-dire votre choix uniquement comme séparateur.
J'ai eu un problème similaire, j'avais une liste et je dois construire un script SQL basé sur un modèle (qui contenait @INPUT@
comme élément à remplacer):
for i in LIST
do
awk "sub(/\@INPUT\@/,\"${i}\");" template.sql >> output
done
Traitement des VARIABLES dans 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