J'ai un ensemble de remplacements sed dans un script bash et j'obtiens une erreur concernant une commande `s 'non terminée. Voici à quoi ressemble la ligne 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
Pour une raison quelconque, bash n'aime pas cela et j'obtiens une erreur
sed: -e expression #4, char 69: unterminated `s' command
Qu'est-ce que j'oublie ici? Comment puis-je demander à SED de saisir la variable? Il me semble qu'ils sont tous terminés.
shell-script
text-processing
sed
Mike B
la source
la source
Réponses:
Vous ne pouvez pas interpoler une variable en toute sécurité dans une commande sed, car la substitution est effectuée par le shell, pas par sed. La valeur de la variable devient la syntaxe sed. Par exemple, dans
"s/TMPFOO1/$FOO1/"
, si$FOO1
contient une nouvelle ligne, cela provoquera une erreur de syntaxe comme celle que vous avez observée. Si$FOO1
contient un/
, cela met fin à las
commande et peut provoquer une erreur ou entraîner l'exécution d'autres commandes (si ce qui se trouve après la/
syntaxe sed est valide).Bien que vous puissiez effectuer une première passe de substitution de
FOO1
pour citer ses caractères spéciaux à inclure dans cette commande sed, il est beaucoup plus simple d'utiliser awk. Awk a une notion de variable et une syntaxe de ligne de commande pour définir la valeur initiale d'une variable.la source
-v
doit précéder chaque déclaration de variable.L'une de vos
$FOO
variables contient probablement des caractères spéciaux qui sont interprétés parsed
.J'ai une autre version
sed
qui génère d'autres messages d'erreur mais voici un exemple d'un problème similaire:Dans ce cas,
$VAR
contient un caractère qui est interprété parsed
comme la barre oblique de fin.la source
Comme d'autres l'ont mentionné ici, cela dépend du contenu de vos variables FOO *. Dans votre cas, utiliser
sed
n'est pas le bon choix car il contient probablement des caractères spéciaux.Jetez un oeil à ce lien et voyez la fonction
gsub_literal
Puisque
gsub_literal
lit depuis stdin et écrit vers stdout, l'utilisation sera:gsub_literal "$search" "$replace" < /home/foo/template > /home/foo/template/finishedresult
Exemple de sortie:
la source
Le problème a été résolu pour moi en essayant des barres obliques inverses supplémentaires dans la
sed 's/.../.../g'
commande. Cette commandem'a donné ce message d'erreur
quand il a été exécuté dans le cadre d'un script c-shell, et il l'a fait uniquement avec une version récente de
sed
, pas avec une version plus ancienne. (Étrangement, la même commande fonctionne bien quand elle est donnée sur la ligne de commande (dans un shell tc)).Le problème avec le script c-shell a été résolu en faisant précéder le
ä
caractère d'une barre oblique inverse:la source