Wie kann verhindert werden, dass Sed das Dateiformat ändert?

Wie kann verhindert werden, dass Sed das Dateiformat ändert?

Ich habe versucht, eine Datei mithilfe einer Sed-Datei vorzuverarbeiten, aber die Ausgabe von Sed scheint das Format zu ändern. Wie kann ich das vermeiden?

file A.txt
A.txt UTF-8 Unicode English text, with very long lines

sed -f process.sed < A.txt > B.txt

head -2 process.sed
#!/bin/sed -f
s/[‘’"“”•·・、。《》™®\.★☆]\\[a-z\-]\+ //g

file B.txt
Non-ISO extended-ASCII English text, with very long lines, with LF, NEL line terminators

Da B.txt nicht UTF-8 kodiert ist, kann ich folgende Verarbeitung nicht durchführen.

vim B.txt
è·¯æ<98><93>æ<96>¯ Âç½<97>å¾·é<87><8c>æ ¼æ<96>¯ //è·¯æ<98><93>æ<96>¯Â·ç½<97>å¾·é<87><8c>æ ¼æ<96>¯ ]

Antwort1

Das Problem besteht darin, dass die Regexp-Engine von sed weder Ihre Eingabedatei noch Ihren […]Abgleich als eine Liste von Unicode-Zeichen sieht. Stattdessen sieht sie jeden von ihnen als mehrere unabhängige Bytes. Beispielsweise sieht sie sie als drei Bytes \xe2 \x80 \xa2und versucht, jeden von ihnen einzeln mit abzugleichen [ \xe2 \x80 \x98 \xe2 \x80 \x99 \x22 \xe2 \x80 ... ].

In dem Beispiel, das Sie in Ihrem Beitrag gezeigt haben, gleicht der reguläre Ausdruck nur das letzte Byte jedes Satzzeichens ab und löscht es, lässt die anderen beiden aber bestehen. Dadurch erhalten Sie eine ungültige (nicht UTF-8) Ausgabedatei.

Mit GNU sed (getestet auf 4.5) kann dies vermieden werden, indem sichergestellt wird, dass dieSystemgebietsschema(die Umgebungsvariablen $LANG oder zumindest $LC_CTYPE) ist auf ein UTF-8-kompatibles Gebietsschema eingestellt. Beispiel:

$ export LANG='C'
$ echo ''test' “test”' | sed 's/[“”•]/X/g'
XX�TestXX� XXXtestXXX
$ echo '•_test' | sed 's/[•‡]_/X_/'
��X_test

$ export LANG='en_US.UTF-8'
$ echo ''test' “test”' | sed 's/[“”•]/X/g'
'test' XtestX
$ echo '•_test' | sed 's/[•‡]_/X_/'
X_test

(Die Landessprache spielt keine Rolle.BeliebigDas UTF-8-Gebietsschema funktioniert.)

Wenn dies bei Ihnen nicht funktioniert, vermeiden Sie es […]vollständig und verwenden Sie \(…\|…\|…\)(oder (…|…|…)in sed -r), was eine Alternative für mehrere Zeichen ist und unabhängig davon funktioniert, wie diese Zeichen letztendlich interpretiert werden.

$ export LANG='C'
$ echo ''test' „test“' | sed 's/\(“\|”\|•\)/X/g'
'test' XtestX
$ echo '•_test' | sed 's/\(•\|‡\)_/X_/'
X_test

verwandte Informationen