tr: Apostroph in ASCII konvertieren

11

Ich versuche , ein konvertieren Rechte einfachen Anführungszeichen zu einem Apostroph mit tr.

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

gegeben eine UTF-8-codierte Datei namens, adie dieses Beispiel enthält:

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

OS X verwendet das BSD trund liefert ein schönes Ergebnis:

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

Ubuntu verwendet die GNU trund erzeugt dieses böse Ergebnis:

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

Wie kann ich diese Konvertierung in Ubuntu durchführen?

plamtrue
quelle
Auch versucht: tr $ '\ xE2 \ x80 \ x99' $ '\ x27' <a-> b mit den gleichen Ergebnissen.
plamtrue
1
Dies ist gut zu wissen, ASCII und Unicode Anführungszeichen
αғsнιη
2
echo It’s easy | perl -CS -Mutf8 -pe "tr/’/'/"
Tchrist

Antworten:

16

Sie könnten ein anderes Werkzeug versuchen, wie sed:

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

Oder verwenden Sie den yBefehl für sed:

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

GNUtr funktioniert vermutlich nicht, weil:

Derzeit trwerden nur Einzelbyte-Zeichen vollständig unterstützt. Schließlich werden Multibyte-Zeichen unterstützt. Wenn dies der Fall ist, wird die -C Option den Zeichensatz ergänzen, während -c sie den Wertesatz ergänzt. Diese Unterscheidung ist nur dann von Bedeutung, wenn einige Werte keine Zeichen sind. Dies ist nur in Gebietsschemas möglich, in denen Multibyte-Codierungen verwendet werden, wenn die Eingabe Codierungsfehler enthält.

Und ist ein Multibyte-Charakter:

$ echo -n \' | wc -c
1
$ echo -n  | wc -c  
3
muru
quelle
1
sedist viel schöner für diese Art von Arbeit.
Kaz Wolfe
2
Um den letzten Teil weiter zu erklären: Ersetzt trjedes der drei Bytes separat durch ', daher '''ebenso wie die unterbrochenen Sequenzen, in denen zwei der drei Bytes in den ähnlichen Zeichen und ersetzt wurden . Stattdessen sollten die drei Bytes zusammen ein Zeichen bedeuten und stattdessen ersetzt werden.
Deltab
Zum besseren Verständnis handelt es sich um ein Multibyte-Zeichen. Außerdem können wir den tr -c '[:print:][:cntrl:]' '-'Befehl verwenden, um jedes nicht druckbare Zeichen außer gültigen Steuerzeichen durch ein zu ersetzen -. Und Sie werden sehen, wie einzelne in 3 Bytes von Zeichen wie übersetzt werden ---. guter Punkt für Multi-Byte-Zeichen.
αғsнιη
9

Wenn Sie auch die doppelten Anführungszeichen und möglicherweise andere Zeichen konvertieren möchten, können Sie GNU verwendeniconv :

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

Das //TRANSLITSuffix gibt an, iconvdass Zeichen außerhalb des Repertoires der Zielcodierung (hier ASCII) ähnlich aussehende Zeichen oder Sequenzen automatisch ersetzen können. Ohne das Suffixiconv gibt es auf, sobald es einen nicht übersetzbaren Charakter findet.

Beachten Sie, dass //TRANSLITdies eine GNU-Erweiterung zu sein scheint: POSIXiconv unterstützt sie nicht.

Deltab
quelle
+1. Wenn Sie einen Text von einem Zeichensatz (oder einer Codierung) in einen anderen konvertieren, kann es sinnvoll sein, ein für diesen Zweck entwickeltes Tool zu verwenden.
RedGrittyBrick
@deltab Ihre Lösung ersetzt auch doppelte Anführungszeichen, die OP nicht ersetzen möchte.
αғsнιη
@ KasiyA Vielleicht sollten sie.
Gerrit
3

Sie können eine dieser awkLösungen verwenden:

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

Oder

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

Verwenden Sie die -sOption tr :

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

Von man tr :

--truncate-set1
          first truncate SET1 to length of SET2
Skippy le Grand Gourou
quelle
1
Ihre Lösung ersetzt auch doppelte Anführungszeichen, die OP nicht ersetzen möchte
αғsнιη
Ah, in der Tat, danke, dass Sie darauf hingewiesen haben. Ich werde diese Antwort als Referenz hinterlassen.
Skippy le Grand Gourou