Comment échapper des caractères spéciaux dans une chaîne?

En supposant que $file détient la valeur dun nom de fichier, dites Dr" A.tif. Dans la programmation bash, comment pourrais-je échapper aux guillemets simples et à tout autre caractère spécial de $file sans supprimer le caractère spécial?

Mise à jour du 9 juillet 2014

Comme demande de @Gilles , extrait de code suivant qui « ne peut pas gérer Dr" A.tif:

files=$(find /path/ -maxdepth 1 -name "*.[Pp][Dd][Ff]" -o -name "*.[Tt][Ii][Ff]") echo "${files}" > ${TEMP_FILE} while read file do newfile=$(echo "${file}" | sed "s, ,\\ ,g") ## line 1 done < ${TEMP_FILE} 

Après avoir essayé le réponse de @Patrick sur line 1, cela semble fonctionner pour moi. Mais si jai un fichier tel que Dr\^s A.tif, la commande printf ne semble pas aider, elle me montre Dr\^s\ A.tif. Si je l’essaye manuellement sur console comme ceci:

printf "%q" "Dr\^s A.tif"

Jaurai cette sortie:

Dr\\\^s\ A.tif

Avez-vous une idée de comment gérer cela?

Commentaires

  • dans quoi contexte prévoyez-vous dutiliser $ file? ou est-ce que ce problème affecte la chaîne avec le caractère spécial à $ file?
  • En fait, la commande find me renvoie un tableau de liste de fichiers. Et puis je parcourt cette liste de fichiers dans la variable $ file.
  • Vous ' avez reçu des réponses correctes ici, mais ce ne sont probablement pas les réponses à la question que vous ' posez vraiment. Daprès votre commentaire, je soupçonne fortement que vous ' êtes sur la mauvaise voie. Nous pouvons ' t vous aider beaucoup parce que vous continuez de ne pas afficher votre code. Je vous recommande cependant de lire Pourquoi mon script shell sétouffe-t-il avec des espaces ou dautres caractères spéciaux? en arrière-plan. Montrez votre script et expliquez ce que vous voulez faire.

Réponse

Vous peut utiliser le printf intégré avec %q pour accomplir cela. Par exemple:

$ file="Dr" A.tif" $ printf "%q\n" "$file" Dr\"\ A.tif $ file=" foo$bar\baz`" $ printf "%q\n" "$file" \ foo\$bar\\baz\` 

De la documentation bash sur printf:

In addition to the standard format specifications described in printf(1) and printf(3), printf interprets: %b expand backslash escape sequences in the corresponding argument %q quote the argument in a way that can be reused as shell input %(fmt)T output the date-time string resulting from using FMT as a format string for strftime(3) 

Commentaires

  • Ce ne fonctionne pas ' avec certains cas .eg lorsque vous devez conserver les guillemets doubles.
  • @ user3467349 cela fonctionne très bien avec les guillemets. Je ' parie que vous ' essayez quelque chose comme printf '%s' "foo". Vous devez dabord comprendre comment lanalyse des arguments fonctionne dans le shell. Voir gnu.org/software/bash/manual/bash.html#Shell-Operation # 2 se produit avant le # 6.
  • Pourriez-vous fournissez un exemple de cette chaîne imprimée avec printf et aucune autre manipulation It doesn't have a: ""
  • Votre problème na rien à voir avec printf. Votre problème est que vous ' ne voulez pas que le shell analyse votre chaîne. Pour ce faire, vous devez passer votre entrée au shell dune manière où il nessaye même pas de lanalyser. '. Une façon de procéder serait de read -r -p 'input: ' && printf '%q\n' "$REPLY", et de fournir lentrée lorsque vous y êtes invité.
  • Comme je ' ve dit plusieurs fois maintenant. Ne pas savoir comment transmettre des données brutes au shell nest ' t un problème avec printf. Vous devriez peut-être poser une question plutôt que critiquer une solution qui n’a rien à voir avec votre problème.

Réponse

Essayez: –

file=Dr\"\ A.tif echo $file Dr" A.tif 

ou

file="Dr" A.tif" echo $file Dr" A.tif 

ou si la chaîne contient un double quote: –

file="Dr" A.tif" echo $file Dr" A.tif 

Il existe de bons tutoriels sur les échappements et les citations sur le net. Commencez par celui-ci .

Réponse

Vous ne « Vous navez pas besoin déchapper aux noms de fichiers que vous manipulez dans un script. Léchappement nest nécessaire que si vous voulez mettre un nom de fichier comme littéral dans un script, ou pour passer plusieurs noms de fichiers en un seul flux dentrée vers un autre script.

Étant donné que vous « bouclez sur la sortie de find, ceci est lun des moyens les plus simples (!) de gérer tous les chemins possibles :

while IFS= read -r -d "" do file_namex="$(basename -- "$REPLY"; echo x)" file_name="${file_namex%$"\nx"}" do_something -- "$file_name" done <(find "$some_path" -exec printf "%s\0" {} +) 

Réponse

rapide et (très) sale

find . | sed "s/^/"/" | sed "s/$/"/" 

Réponse

Beaucoup de ces réponses, y compris la réponse la plus votée en utilisant printf "%q" ne fonctionne pas dans tous les cas sans manipulation supplémentaire.Je suggérerais ce qui suit (exemple ci-dessous):

cat <<EOF; 2015-11-07T03:34:41Z app[postgres.0000]: [TAG] text-search query doesn"t contain lexemes: "" EOF

Commentaires

  • Excusez la question n00b, mais pouvez-vous expliquer comment vous utiliseriez réellement cela pour échapper des caractères dans une chaîne? Si je copie le code que vous écrivez dans mon terminal, il imprime simplement 2015-11-07T03: 34: 41Z app [postgres.0000]: [TAG] la requête de recherche de texte ne ' t contiennent des lexèmes: " " … rien nest échappé.
  • Que ' est littéralement le point, tous les caractères spéciaux sont interprétés comme des caractères littéraux et non pour leur signification particulière. Essayez plutôt de faire écho " la chaîne ci-dessus " pour voir la différence.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *