Commande pour échapper une chaîne dans bash

99

J'ai besoin d'une commande bash qui convertira une chaîne en quelque chose qui est échappé. Voici un exemple:

echo "hello\world" | escape | someprog

Où la commande d'échappement "hello\world"entre "hello\\\world". Ensuite, someprog peut utiliser "hello\\world"comme il s'y attend. Bien sûr, ceci est un exemple simplifié de ce que je vais vraiment faire.

Utilisateur1
la source
5
Quelle est la nature de l'évasion? En d'autres termes, quels caractères doivent être échappés? Cherchez-vous un échappement de style C ++ (où les tabulations sont remplacées par \ t, les nouvelles lignes avec \ n, les guillemets avec \ ", etc.)? Il est difficile d'aider sans que le problème soit bien défini.
Michael Aaron Safyan
2
duplication possible de l' écho qui échappe les arguments
P Shved
Cette question pourrait signifier une douzaine de choses différentes. Au lieu de nous faire deviner, il serait utile d'indiquer exactement le type d'évasion que vous recherchez.
Don Hatch
1
La question était spécifique à l'utilisation de \\ pour \. Il y a une réponse acceptée.
User1

Réponses:

155

Dans Bash:

printf "%q" "hello\world" | someprog

par exemple:

printf "%q" "hello\world"
hello\\world

Cela pourrait également être utilisé via des variables:

printf -v var "%q\n" "hello\world"
echo "$var"
hello\\world
Suspendu jusqu'à nouvel ordre.
la source
6
Remarquez, a %qété brisé pendant plus d'une décennie jusqu'à environ 2012. Il a eu des problèmes avec ~. Il existe également des one-liners sed portables stackoverflow.com/a/20053121/1073695
Jo So
1
sed est en effet meilleur car il peut aussi échapper aux signes dollar
untore
2
@untore: a='abc$def":'; printf '%q\n' "$a"donne abc\$def\":(le signe dollar est échappé). C'est Bash 4.3 (j'ai obtenu le même résultat dans Bash 3.2). Quelle version utilisez-vous?
Suspendu jusqu'à nouvel ordre.
3
pour échapper au signe dollar, utilisez plutôt des guillemets simples, par exemple:printf "%q" 'he$l&lo\world'
LeandroCR
bash printf '%q\n' textcite le texte au bashformat (et pour la locale actuelle), de sorte que cela ne fonctionnerait que dans le cas de l'OP s'il someprogavait exactement la même syntaxe de citation que bashce qui est hautement improbable.
Stephane Chazelas
9

Pure Bash, utilisez la substitution de paramètres:

string="Hello\ world"
echo ${string//\\/\\\\} | someprog
Fritz G. Mehner
la source
1
de cette façon, "bonjour le monde" n'est pas échappé à "bonjour \ monde" - une approche printf dans la réponse acceptée le fait.
vchrizz
1
De plus, "% q" n'échappe pas à '/' comme dans "03/25/2017" dont j'avais besoin pour être échappé à "03 \ / 25 \ / 2017" (afin qu'il puisse être dans un '/' régulier délimité expression).
wrlee
0

Vous pouvez utiliser perl pour remplacer divers caractères, par exemple:

$ echo "Hello\ world" | perl -pe 's/\\/\\\\/g'
Hello\\ world

Selon la nature de votre évasion, vous pouvez enchaîner plusieurs appels pour échapper aux personnages appropriés.

Michael Aaron Safyan
la source
1
Pourquoi pas sed? $ echo "hello \ world" | sed 's / \\ / \\\\ /'
Espace
1
@Octopus, c'est aussi une option valide. Je suis plus à l'aise avec perl, mais oui, ça marche aussi.
Michael Aaron Safyan