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 du shell, vous devez arrêter et `` citer '' la $varname
partie afin qu'elle ne soit pas substituée directement, ce que j'ai fait et qui ne fonctionne que si la variable est définie immédiatement avant.
Comment puis-je obtenir sed pour reconnaître une $var
variable d'environnement comme il est défini dans le shell?
set -x
dans le shell pour que le shell fasse écho à chaque commande juste avant de les exécuter. Cela peut dissiper beaucoup de confusion. (En outre, j'utilise souventset -u
pour faire du déréférencement des variables non définies une erreur difficile. (Voirset -e
aussi.))Réponses:
Vos deux exemples semblent identiques, ce qui rend les problèmes difficiles à diagnostiquer. Problèmes potentiels:
Vous devrez peut-être des guillemets doubles, comme dans
sed 's/xxx/'"$PWD"'/'
$PWD
peut contenir une barre oblique, auquel cas vous devez trouver un caractère non contenu dans$PWD
pour l'utiliser comme délimiteur.Pour résoudre les deux problèmes à la fois, peut-être
la source
En plus de la réponse de Norman Ramsey, je voudrais ajouter que vous pouvez citer deux fois la chaîne entière (ce qui peut rendre l'instruction plus lisible et moins sujette aux erreurs).
Donc, si vous voulez rechercher 'foo' et le remplacer par le contenu de $ BAR, vous pouvez mettre la commande sed entre guillemets.
Dans le premier, $ BAR ne se développera pas correctement tandis que dans le second $ BAR se développera correctement.
la source
"2,$s/^/$foo/"
que$s
obtient également interprété comme une variable et cela ne devrait pas.Vous pouvez utiliser d'autres caractères que "/" en remplacement:
la source
sed
comme le barfing en raison de l'interprétation/
du contenu de $ 2. C'était exactement ce dont j'avais besoin pour le dépasser. Merci pour un bon conseil!Une autre alternative simple:
Puisque
$PWD
contiendra généralement une barre oblique/
, utilisez|
plutôt que/
pour l'instruction sed:la source
$PWD
...?Avec la modification de votre question, je vois votre problème. Disons que le répertoire courant est
/home/yourname
... dans ce cas, votre commande ci-dessous:sera étendu à
ce qui n'est pas valable. Vous devez mettre un
\
caractère devant chacun/
dans votre $ PWD si vous voulez le faire.la source
mauvaise façon: changer le délimiteur
peut-être que ce n'est pas la réponse finale,
vous ne pouvez pas savoir dans quel personnage apparaîtra
$PWD
,/
:
OU@
.la bonne façon est de remplacer le caractère spécial dans
$PWD
.bonne façon: échapper le délimiteur
par exemple: essayez de remplacer
URL
comme $ url (a:
/
dans le contenu)dans la chaîne $ tmp
une. utiliser
/
comme délimiteurOU
b. utiliser
:
comme délimiteur (plus lisible que/
)la source
En fait, la chose la plus simple (dans gnu sed au moins) est d'utiliser un séparateur différent pour la commande sed substitution (s). Ainsi, au lieu que s / pattern / '$ mypath' / soit développé en s / pattern // my / path / qui confondra bien sûr la commande s, utilisez s! Pattern! '$ Mypath'! qui sera étendu à s! pattern! / my / path! J'ai utilisé le caractère bang (!) (Ou utilisez tout ce que vous voulez) qui évite la barre oblique habituelle, mais en aucun cas votre seul choix comme séparateur.
la source
où VAR contient ce que vous souhaitez remplacer le champ par
la source
Gérer les VARIABLES dans sed
la source
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):la source