
Eu tenho a seguinte string
echo -e "a12\x8fb12\x9f" | xxd
0000000: 6131 328f 6231 329f 0a a12.b12..
e deseja excluir a sequência 12\x9f
e 12\x8f
com sed
.
Eu posso fazer isso com este comando
sed -e 's_12\x8f__g' -e 's_12\x9f__g'
mas por que esse comando não funciona?
sed -e 's_12[\x8f\x9f]__g'
Responder1
Isso seria porque as [...]
correspondências de um personagem. sed
tentaria combinar caracteres com o intervalo especificado em [...]
. Em localidades UTF-8, você só pode encontrar \x8f
como parte de um caractere multibyte. Você notará que .
isso também não corresponde (e isso é um requisito do POSIX).
Por exemplo:
sed 's/[eé\xa9]//'
não faria sentido. é
é um caractere (codificado como 0xc3 0xa9
), 0xa9 não é um caractere, mas sim um byte, pode ser encontrado dentro de um caractere (como é
), e
é um caractere (codificado como 0x65). Você não pode esperar sed
de alguma forma corresponder 0xa9 dentro de um caractere e como um byte.
Para combinar dados de bytes arbitrários com umtextoutilitário como sed
, você desejará usar um local onde os caracteres são bytes, esse é um caso típico paraLC_ALL=C
.
LC_ALL=C sed 's/12[\x8f\x9f]//g'
Ou portável:
LC_ALL=C sed "$(printf 's/12[\217\237]//g')"
Observe que você não pode esperar processar dados contendo caracteres NUL (ou que não terminem em um caractere de nova linha ou onde os caracteres de nova linha tenham mais do que alguns quilobytes separados) de forma portável com sed
. Use perl -p/-n
em vez disso nesse caso.