
私は次の文字列を持っています
echo -e "a12\x8fb12\x9f" | xxd
0000000: 6131 328f 6231 329f 0a a12.b12..
シーケンスを削除し12\x9f
、12\x8f
を使用しますsed
。
このコマンドでできます
sed -e 's_12\x8f__g' -e 's_12\x9f__g'
しかし、なぜこのコマンドは機能しないのでしょうか?
sed -e 's_12[\x8f\x9f]__g'
答え1
[...]
これは、文字の一致によるものです。sed
は、 で指定された範囲に対して文字を一致させようとします[...]
。 UTF-8 ロケールでは、 はマルチバイト文字の一部としてのみ発生します。も一致しない\x8f
ことがわかります(これは POSIX の要件です)。.
例えば:
sed 's/[eé\xa9]//'
は意味をなさないでしょう。é
は文字 ( としてエンコード0xc3 0xa9
) であり、0xa9 は文字ではなくバイトであり、文字内 ( などé
) に存在し、は文字 (0x65 としてエンコード) です。 0xa9 を文字内とバイトの両方で一致させることができるとはe
期待できません。sed
任意のバイトデータを文章のようなユーティリティではsed
、文字がバイトであるロケールを使用する必要があります。これは、LC_ALL=C
。
LC_ALL=C sed 's/12[\x8f\x9f]//g'
またはポータブル:
LC_ALL=C sed "$(printf 's/12[\217\237]//g')"
NUL 文字を含むデータ (または改行文字で終わらないデータ、または改行文字の間隔が数キロバイト以上あるデータ) を で移植可能に処理することは期待できないことに注意してくださいsed
。perl -p/-n
その場合は、代わりに を使用してください。