Échapper à une chaîne pour un sed remplacer motif
Dans mon script bash que j'ai un externe (reçus de l'utilisateur) chaîne de caractères, qui je dois l'utilisation de sed modèle.
REPLACE="<funny characters here>"
sed "s/KEYWORD/$REPLACE/g"
Comment puis-je échapper à la $REPLACE
chaîne de sorte qu'il serait en sécurité acceptée par sed
comme un littéral de remplacement?
REMARQUE: La KEYWORD
est un muet sous-chaîne avec pas de matches etc. Il n'est pas fourni par l'utilisateur.
- Êtes-vous en essayant d'éviter le "Petit Bobby Tables" problème si ils disent "/g -e 's/MOT de passe=.*/MOT de passe=abc/g'"?
- Oui, celui-là aussi.
- Si vous utilisez bash, vous n'avez pas besoin de sed. Utilisez simplement
outputvar="${inputvar//"$txt2replace"/"$txt2replacewith"}".
- Je pense que vous ne devriez pas mettre les deux variables en dehors de la cite. Bash peut lire des variables à l'intérieur des guillemets (dans votre exemple, les espaces pourraient vis les choses).
- Voir aussi: stackoverflow.com/q/29613304/45375
- voir mon commentaire sur ma propre réponse. Les guillemets à l'intérieur de l' ${} ne correspondent pas avec les guillemets à l'intérieur. Les deux variables ne sont pas à l'extérieur de la cite.
- vous avez raison.
- connexes: superuser.com/questions/422459/...
Vous devez vous connecter pour publier un commentaire.
Avertissement: Ce n' pas envisager des retours à la ligne. Pour un plus en profondeur réponse, voir cette question à la place. (Merci, Ed Morton & Niklas Pierre)
Remarque qu'échapper à tout ce qui est une mauvaise idée. Sed a besoin de beaucoup de caractères à échapper à obtenir une signification particulière. Par exemple, si vous échappez un chiffre dans la chaîne de remplacement, il sera à son tour à une référence arrière.
Ben Vierge a dit, il y a seulement trois caractères doivent être échappés dans la chaîne de remplacement (échappe à eux-mêmes, barre oblique de fin d'instruction et & pour remplacer tous):
Si jamais vous avez besoin pour échapper à la
KEYWORD
chaîne, ce qui suit est celui dont vous avez besoin:Rappelez-vous, si vous utilisez un caractère autre que
/
comme délimiteur, vous avez besoin de remplacer la barre oblique dans les expressions ci-dessus avec le personnage que vous utilisez. Voir PeterJCLaw commentaire pour l'explication.Édité: en Raison de certains cas de coin auparavant pas pris en compte, les commandes ci-dessus ont changé plusieurs fois. Cochez la case modifier l'histoire pour plus de détails.
KEYWORD
, dans GNU sed, voici 2 autres caractères^
,$
ne sont pas mentionnés ci-dessus:s/[]\/$*.^|[]/\\&/g
sed s/\[.]/_/g
à l'opposésed s/\.foo/_foo/g
(
et)
ne doit pas être échappé. Ils n'ont pas de signification particulière par défaut, et d'échapper à leur donne eux une signification particulière. (GNU sed 4.2.2)"
que shell limitation, si elle est utilisée dans les sed modèle grâce à la substitution de variable ?A='foo"bar' echo $A | sed s/$A/baz/
en bash. Les guillemets sont traités comme la " foo " et " bar " autour d'elle.A='I am a fine"guy'; echo $A | sed -e "s/$A/Sorry I am dummy, learn first/"
me faire plaisir mais ...sed -e 's/[\/&]/\\&/g'
semble être la seule à donner \\\\ comme sa sortie. Qui serait seulement de résoudre le 2 barres obliques inverses à droite? Je pense qu'il devrait en fait être de donner 6 barres obliques inverses. Ce qui peut être fait pour résoudre le sed de commande?TARGET="-e \foo"; echo $TARGET
. Vous pouvez utiliser printf place:printf '%s\n' "$TARGET"
printf '%s\n' '\\\' | sed -e 's/[\/&]/\\&/g'
there are only three characters that need to be escaped in the replacement string
- non, vous avez aussi besoin de barres obliques inverses, quand ils sont remplacé par un chiffre, par exemple\1
, ou ils seront traités comme une référence à un groupe correspondant. Voir stackoverflow.com/questions/29613304/... pour savoir comment faire ce travail de manière robuste.{}
dans la chaîne. J'ai modifié pour êtresed -e 's/[\/&}]/\\&/g'
et qui semblait le fixer.echo 'Foo\1bar' | sed -e 's/[\/&]/\\&/g'
si vous êtes dans le doute. Votre lien est une vraiment bonne, dans la profondeur de réponse, donc j'ai ajouté un avertissement et votre lien vers la réponse. Merci.echo 'Foo' | sed -e 's/o/a{b}c/'
}
j'ai eu cette erreur:sed: bad option in substitution expression
|
à partir de la clé de remplacement, trop. Exemple:sed 's/\|/x/g' <<< abc
donnexaxbxcx
, donc|
ne doit pas être échappés ou utilisé comme délimiteur aussi. FYI:sed (GNU sed) 4.2.2
|
gains de signification particulière, en étant échappé de là. Fixe. Merci à vous, @TinoKEYWORD
chaîne -- au début et à la fin? Ne faudrait-il pas paire sera suffisant?[...]
expression qui arrive à avoir]
en tant que premier et[
comme dernier élément dans la liste.La sed de commande vous permet d'utiliser d'autres caractères au lieu de
/
comme séparateur:Les guillemets ne sont pas un problème.
.
qui, autrement, a une signification particulière. J'ai édité votre réponse.sed '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file
avecsed '|CLIENTSCRIPT="foo"|a CLIENTSCRIPT2="hello"' file
et qui ne fait pas de même.s
de commande (comme remplaçant) de sed permet d'utiliser d'autres caractères au lieu de / comme séparateur. Aussi, ce serait une réponse à comment utiliser sed sur les URL avec des caractères barre oblique. Il ne répond pas à l'OP question de savoir comment échapper à une chaîne entrée par l'utilisateur, qui peut contenir /, \, mais aussi # si vous décidez de l'utiliser. Et d'ailleurs, URI peut contenir # tropLes trois seuls caractères littéraux qui sont spécialement traités dans le remplacement de la clause sont
/
(pour fermer la clause),\
(pour échapper les caractères, la référence arrière, &c.), et&
(notamment le match dans la zone de remplacement). Donc, tout ce que vous devez faire est de s'échapper de ces trois personnages:Exemple:
echo '[a](!)' | sed 's/[a](!)/[a]/'
(avec GNU sed à l'intérieur de bash) résultat de la[a](!)
au lieu de[a]
?Basé sur Pianosaurus est d'expressions régulières, j'ai fait une fonction bash, qui échappe à la fois de mots clés et de remplacement.
Voici comment l'utiliser:
man echo
), provoquant la conduite à se comporter de façon inattendue lorsque votre argument$1
commence par un tiret. Au lieu de cela, vous pouvez commencer votre tuyau avecprintf '%s\n' "$1"
.C'est un peu tard pour répondre... mais il y a un moyen beaucoup plus simple pour ce faire. Il suffit de changer le séparateur (c'est à dire, le caractère qui sépare les champs). Ainsi, au lieu de
s/foo/bar/
vous écrires|bar|foo
.Et, voici le moyen le plus facile pour ce faire:
La sortie qui en est dépourvu de ce méchant DÉFINISSEUR de la clause.
&
et ` doit toujours être échappé, comme doit le délimiteur, selon ce qui est choisi.$
dans la chaîne sur le point d'être changé, et de maintenir le sens de l'$
dans la chaîne de remplacement. dire que je veux changer$XXX
à la valeur de la variable$YYY
,sed -i "s|\$XXX|$YYY|g" file
fonctionne très bien.Il s'avère que vous vous posez la mauvaise question. J'ai aussi posé la mauvaise question. La raison, c'est mal, c'est le début de la première phrase: "Dans mon bash script...".
J'ai eu la même question & fait la même erreur. Si vous utilisez bash, vous n'avez pas besoin d'utiliser sed pour faire de la chaîne de remplacement (et c'est beaucoup nettoyant à utiliser la fonction remplacer construit en bash).
Au lieu de quelque chose comme, par exemple:
vous pouvez utiliser bash caractéristiques exclusivement:
$A
et$B
sont non cotées, mais ils ne le sont pas. Les guillemets à l'intérieur de la${}
ne correspondent pas avec les guillemets à l'extérieur.var='has space'
) –OUTPUT=${INPUT//"$A"/"$B"}
est sûr.var1=$var2
ne peut se briser, peu importe ce que vous avez dansvar2
: glob caractères, espaces, retours à la ligne... Mais en citant il ne fait pas de mal, bien sûr.Utiliser awk - c'est plus propre:
awk
est qu'il n'a rien de semblable àsed -i
, qui vient très pratique, 99% du temps.Voici un exemple d'un AWK j'ai utilisé il y a longtemps. C'est un AWK qui imprime de nouveaux AWKS. AWK et SED étant similaires, il peut être un bon modèle.
Il semble excessif, mais en quelque sorte que la combinaison de devis travaux à garder le ' imprimés comme des littéraux. Alors si je me souviens bien le vaiables sont juste entourés de guillemets comme ceci: "$1". Essayez-la, laissez-moi savoir comment cela fonctionne avec le SED.
J'ai une amélioration par rapport à la sedeasy fonction, qui VA rompre avec les caractères spéciaux comme onglet.
Alors, quoi de différent?
$1
et$2
enveloppé dans des guillemets pour éviter shell expansions et de préserver les tabulations ou des espaces de double.Supplémentaire de la tuyauterie
| sed -e 's:\t:\\t:g'
(j'aime:
token) qui transforme un onglet dans\t
.n'oubliez pas, tout le plaisir qui se produisent avec le shell limitation autour "et"
(dans ksh)
Si le cas se trouve être que vous générez un mot de passe aléatoire pour passer à
sed
remplacer le modèle, puis vous choisissez d'être prudent sur le jeu de caractères dans la chaîne de caractères aléatoires. Si vous choisissez un mot de passe composé par le codage d'une valeur en base64, il est est le seul personnage qui est à la fois possible en base64 et est également un caractère spécial danssed
remplacer le modèle. Ce caractère est "/", et s'enlève facilement le mot de passe de la production:Si vous êtes simplement à la recherche pour remplacer la valeur de la Variable dans la commande sed puis il suffit de supprimer
Exemple:
Un moyen plus facile de le faire est de simplement construire la chaîne avant de la main et de l'utiliser comme un paramètre pour
sed
REPLACE=/
donnesed: -e expression #1, char 12: unknown option to `s'