
Estaba intentando usar un archivo sed para preprocesar un archivo, pero la salida de sed parece cambiar el formato. ¿Cómo debo evitarlo?
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
Debido a que B.txt no está codificado en UTF-8, no puedo realizar el siguiente procesamiento.
vim B.txt
è·¯æ<98><93>æ<96>¯ Âç½<97>å¾·é<87><8c>æ ¼æ<96>¯ //è·¯æ<98><93>æ<96>¯Â·ç½<97>å¾·é<87><8c>æ ¼æ<96>¯ ]
Respuesta1
El problema es que el motor de expresiones regulares de sed no ve su archivo de entrada ni su […]
coincidencia como una lista de caracteres Unicode; en cambio, ve cada uno de ellos como múltiples bytes independientes. Por ejemplo, ve •
tres bytes \xe2 \x80 \xa2
e intenta comparar cada uno de ellos individualmente [ \xe2 \x80 \x98 \xe2 \x80 \x99 \x22 \xe2 \x80 ... ]
.
Entonces, en el ejemplo que mostró en su publicación, la expresión regular solo coincide y elimina el último byte de cada carácter de puntuación, pero deja los otros 2 todavía allí. Eso es lo que le da un archivo de salida no válido (no UTF-8).
Con GNU sed (probado en 4.5), esto se puede evitar asegurándose de que elconfiguración regional del sistema(las variables de entorno $LANG o al menos $LC_CTYPE) están configuradas en una configuración regional compatible con UTF-8. Por ejemplo:
$ exportar LANG='C' $ echo ''prueba' “prueba”' | sed 's/[“”•]/X/g' XX�pruebaXX� XXXpruebaXXX $ eco '•_prueba' | sed 's/[•‡]_/X_/' ��X_prueba $ exportar LANG='en_US.UTF-8' $ echo ''prueba' “prueba”' | sed 's/[“”•]/X/g' 'prueba' XtestX $ eco '•_prueba' | sed 's/[•‡]_/X_/' X_prueba
(El idioma local no importa.CualquierLa configuración regional UTF-8 funcionará).
Si esto no funciona para usted, evítelo […]
por completo y use \(…\|…\|…\)
(o (…|…|…)
en sed -r), que es una alternativa de varios caracteres y funcionará independientemente de cómo se terminen interpretando esos caracteres.
$ exportar LANG='C' $ echo ''prueba' “prueba”' | sed 's/\(“\|”\|•\)/X/g' 'prueba' XtestX $ eco '•_prueba' | sed 's/\(•\|‡\)_/X_/' X_prueba