tr: convertir l'apostrophe en ASCII

11

J'essaie de convertir un guillemet simple droit en une apostrophe en utilisant tr.

tr "`echo -e '\xE2\x80\x99'`" "`echo -e '\x27'`" < a > b

étant donné un fichier codé UTF-8 appelé aqui contient cet exemple:

Were not a different species
All alone?” Jeth mentioned.

OS X utilise le BSD tret produit un joli résultat:

We're not a different species
“All alone?” Jeth mentioned.

Ubuntu utilise le GNU tret produit ce résultat désagréable:

We'''re not a different species
''<9C>All alone?''<9D> Jeth mentioned.

Comment puis-je effectuer cette conversion dans Ubuntu?

plamtrue
la source
Également essayé: tr $ '\ xE2 \ x80 \ x99' $ '\ x27' <a> b avec les mêmes résultats.
plamtrue
1
C'est bon de savoir les guillemets ASCII et Unicode
αғsнιη
2
echo It’s easy | perl -CS -Mutf8 -pe "tr/’/'/"
tchrist

Réponses:

16

Vous pouvez essayer un autre outil, comme sed:

$ sed "s/’/'/g" <a
We're not a different species
“All alone?” Jeth mentioned.

Ou, puisque nous effectuons une traduction simple, utilisez la ycommande pour sed:

$ sed "y/’/'/" <a
We're not a different species
“All alone?” Jeth mentioned.

GNUtr ne fonctionne probablement pas parce que:

Actuellement, trprend entièrement en charge uniquement les caractères à un octet. Finalement, il prendra en charge les caractères multi-octets; dans ce cas, l' -C option la fera compléter l'ensemble de caractères, tandis -c qu'elle complètera l'ensemble de valeurs. Cette distinction n'a d'importance que lorsque certaines valeurs ne sont pas des caractères, et cela n'est possible que dans les paramètres régionaux utilisant des codages multi-octets lorsque l'entrée contient des erreurs de codage.

Et est un caractère multi-octets:

$ echo -n \' | wc -c
1
$ echo -n  | wc -c  
3
muru
la source
1
sedest beaucoup plus agréable pour ce genre de travail.
Kaz Wolfe
2
Pour expliquer la dernière partie plus loin: trremplace chacun des trois octets séparément avec ', d'où '''ainsi que les séquences interrompues où il a remplacé deux des trois octets dans les caractères similaires et . Il doit plutôt comprendre les trois octets comme signifiant ensemble un seul caractère, et les remplacer à la place.
deltab
Pour bien comprendre, un caractère multi-octets peut également être utilisé tr -c '[:print:][:cntrl:]' '-'pour remplacer chaque caractère non imprimable , autre que les caractères de contrôle valides, par un -. Et vous verrez une traduction unique à 3 octets de caractères comme ---. bon point pour le caractère multi-octets.
αғsнιη
9

Si vous souhaitez également convertir les guillemets doubles et peut-être d'autres caractères, vous pouvez utiliser GNUiconv :

$ iconv -f utf-8 -t ascii//translit < a
We're not a different species
"All alone?" Jeth mentioned.

Le //TRANSLITsuffixe indique iconvque pour les caractères en dehors du répertoire de l'encodage cible (ici ASCII), il peut remplacer automatiquement des caractères ou des séquences d'aspect similaire. Sans le suffixe, iconvabandonnera dès qu'il trouvera un caractère intraduisible.

Notez que cela //TRANSLITsemble être une extension GNU: POSIXiconv ne la prend pas en charge.

deltab
la source
+1. Si vous convertissez un texte d'un jeu de caractères (ou encodage) en un autre, il peut être judicieux d'utiliser un outil conçu à cet effet.
RedGrittyBrick
@deltab, votre solution remplace également les guillemets doubles que OP ne souhaite pas les remplacer.
αғsнιη
@KasiyA Peut-être qu'ils devraient.
gerrit
3

Vous pouvez utiliser l'une de ces awksolutions:

awk '{gsub(/\xE2\x80\x99/, "\x27");print}' file # with Hex ASCII code

awk '{gsub(/’/, "\x27");print}' file

awk '{gsub(/\342\200\231/, "\47");print}'  file # with Octal ASCII code

awk '{gsub(/’/, "\47");print}' file

Ou

awk '{gsub(/’/, "'"'"'");print}' file
αғsнιη
la source
0

Utilisez l' -soption de tr :

$ echo "We’re not a different species"|tr -s "’" "'"
We're not a different species

De man tr :

--truncate-set1
          first truncate SET1 to length of SET2
Skippy le Grand Gourou
la source
1
votre solution remplace également les guillemets doubles que OP ne souhaite pas remplacer
αғsнιη
Ah, en effet, merci de l'avoir signalé. Je vais laisser cette réponse pour référence.
Skippy le Grand Gourou