
Ich habe die folgende Zeichenfolge
echo -e "a12\x8fb12\x9f" | xxd
0000000: 6131 328f 6231 329f 0a a12.b12..
und die Sequenz löschen möchten 12\x9f
und 12\x8f
mit sed
.
Ich kann es mit diesem Befehl tun
sed -e 's_12\x8f__g' -e 's_12\x9f__g'
aber warum funktioniert dieser Befehl nicht?
sed -e 's_12[\x8f\x9f]__g'
Antwort1
Das liegt daran, dass die [...]
Übereinstimmungen mit einem Zeichen sed
versuchen würden, Zeichen mit dem in angegebenen Bereich abzugleichen [...]
. In UTF-8-Gebietsschemas können Sie nur \x8f
als Teil eines Multibyte-Zeichens auftreten. Sie werden feststellen, dass .
auch dies nicht zutrifft (und das ist eine POSIX-Anforderung).
Zum Beispiel:
sed 's/[eé\xa9]//'
würde keinen Sinn ergeben. é
ist ein Zeichen (kodiert als 0xc3 0xa9
), 0xa9 ist kein Zeichen, sondern ein Byte, kann innerhalb eines Zeichens gefunden werden (wie é
), e
ist ein Zeichen (kodiert als 0x65). Sie können nicht erwarten, sed
0xa9 sowohl innerhalb eines Zeichens als auch als Byte zu finden.
Um beliebige Byte-Daten mit einemTextDienstprogramm wie verwenden sed
, möchten Sie ein Gebietsschema verwenden, bei dem Zeichen Bytes sind. Dies ist ein typischer Fall fürLC_ALL=C
.
LC_ALL=C sed 's/12[\x8f\x9f]//g'
Oder portabel:
LC_ALL=C sed "$(printf 's/12[\217\237]//g')"
Beachten Sie, dass Sie mit nicht erwarten können, Daten, die NUL-Zeichen enthalten (oder die nicht mit einem Zeilenumbruchzeichen enden oder bei denen die Zeilenumbruchzeichen mehr als ein paar Kilobyte voneinander entfernt sind), portabel zu verarbeiten sed
. Verwenden Sie perl -p/-n
in diesem Fall stattdessen .