
Eu estava tentando usar um arquivo sed para pré-processar um arquivo, mas a saída do sed parece alterar o formato. Como devo evitá-lo?
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
Como B.txt não está codificado em UTF-8, não posso fazer o processamento seguinte.
vim B.txt
è·¯æ<98><93>æ<96>¯ Âç½<97>å¾·é<87><8c>æ ¼æ<96>¯ //è·¯æ<98><93>æ<96>¯Â·ç½<97>å¾·é<87><8c>æ ¼æ<96>¯ ]
Responder1
O problema é que o mecanismo regexp do sed não vê seu arquivo de entrada nem sua […]
correspondência como uma lista de caracteres Unicode; em vez disso, vê cada um deles como vários bytes independentes. Por exemplo, ele vê •
três bytes \xe2 \x80 \xa2
e tenta combinar cada um deles individualmente com [ \xe2 \x80 \x98 \xe2 \x80 \x99 \x22 \xe2 \x80 ... ]
.
Então, no exemplo que você mostrou em sua postagem, a regex apenas corresponde e exclui o último byte de cada caractere de pontuação, mas deixa os outros 2 ainda lá. Isso é o que fornece um arquivo de saída inválido (não UTF-8).
Com o GNU sed (testado em 4.5), isso pode ser evitado certificando-se de que olocalidade do sistema(as variáveis de ambiente $LANG ou pelo menos $LC_CTYPE) estão definidas para um código de idioma compatível com UTF-8. Por exemplo:
$ exportar LANG='C' $ echo ''teste' “teste”' | sed 's/[“”•]/X/g' XX�testeXX� XXXtesteXXX $ echo '•_test' | sed 's/[•‡]_/X_/' ��X_teste $ exportar LANG='en_US.UTF-8' $ echo ''teste' “teste”' | sed 's/[“”•]/X/g' 'teste' XtestX $ echo '•_test' | sed 's/[•‡]_/X_/' X_teste
(O idioma local não importa.QualquerA localidade UTF-8 funcionará.)
Se isso não funcionar para você, evite […]
completamente e use \(…\|…\|…\)
(ou (…|…|…)
em sed -r), que é uma alternativa de vários caracteres e funcionará independentemente de como esses caracteres forem interpretados.
$ exportar LANG='C' $ echo ''teste' “teste”' | sed 's/\(“\|”\|•\)/X/g' 'teste' XtestX $ echo '•_test' | sed 's/\(•\|‡\)_/X_/' X_teste