¿Cómo busco todos los caracteres que no son ASCII?

Resuelto pconrey asked hace 14 años • 16 respuestas

Tengo varios archivos XML muy grandes y estoy intentando encontrar las líneas que contienen caracteres que no son ASCII. Intenté lo siguiente:

grep -e "[\x{00FF}-\x{FFFF}]" file.xml

Pero esto devuelve cada línea del archivo, independientemente de si la línea contiene un carácter en el rango especificado.

¿Tengo mal la sintaxis o estoy haciendo algo más mal? También lo intenté:

egrep "[\x{00FF}-\x{FFFF}]" file.xml 

(con comillas simples y dobles rodeando el patrón).

pconrey avatar Jun 09 '10 03:06 pconrey
Aceptado

Puedes usar el comando:

grep --color='auto' -P -n "[\x80-\xFF]" file.xml

Esto le dará el número de línea y resaltará los caracteres que no sean ASCII en rojo.

En algunos sistemas, dependiendo de su configuración, lo anterior no funcionará, por lo que puede buscar a la inversa

grep --color='auto' -P -n "[^\x00-\x7F]" file.xml

Tenga en cuenta también que el bit importante es la -Pbandera que equivale a --perl-regexp: por lo que interpretará su patrón como una expresión regular de Perl. También dice que

Esto es altamente experimental y grep -P puede advertir sobre características no implementadas.

jerrymouse avatar Feb 22 '2012 13:02 jerrymouse

En lugar de hacer suposiciones sobre el rango de bytes de caracteres no ASCII, como lo hacen la mayoría de las soluciones anteriores, en mi opinión, es un poco mejor ser explícito sobre el rango de bytes real de caracteres ASCII.

Entonces la primera solución, por ejemplo, sería:

grep --color='auto' -P -n '[^\x00-\x7F]' file.xml

(que básicamente busca cualquier carácter fuera del rango ASCII hexadecimal: desde \x00 hasta \x7F)

En Mountain Lion eso no funcionará (debido a la falta de soporte PCRE en BSD grep) , pero si pcrese instala a través de Homebrew, lo siguiente funcionará igual de bien:

pcregrep --color='auto' -n '[^\x00-\x7F]' file.xml

¿Algún pros o contras que alguien pueda pensar?

pvandenberk avatar Dec 04 '2012 12:12 pvandenberk

La forma más sencilla es definir un carácter que no sea ASCII... como un carácter que no es un carácter ASCII.

LC_ALL=C grep '[^ -~]' file.xml

El código anterior busca caracteres que no son caracteres ASCII imprimibles: caracteres que no son ASCII y caracteres de control. Agregue una pestaña después de ^si puede haber pestañas en el archivo. Agregue un retorno de carro si puede haber finales de línea de Windows que no desea que coincidan. En bash o zsh, puedes usar $'…'comillas y \tpara una tabulación, \rpara un retorno de carro.

LC_ALL=C grep $'[^\t\r -~]' file.xml

Con otros shells que no son compatibles $'…', de forma interactiva, puede insertar caracteres de control literalmente con, por ejemplo , . En un script, es posible que prefiera no incluir el carácter de control literalmente en el script y, en su lugar, generarlo en tiempo de ejecución.Ctrl+V Ctrl+M

control_characters=$(printf '\t\r')
LC_ALL=C grep "[^${control_characters} -~]" file.xml

Para evitar que coincida con cualquier carácter de control, utilice el rango de caracteres ASCII (excluyendo nulo que no se puede especificar en la línea de comando). Con GNU grep, los caracteres de control normalmente dan como resultado el mensaje "coincidencias de archivos binarios" en lugar de imprimir coincidencias; pase la --textopción para mostrar caracteres de control en la salida.

LC_ALL=C grep --text $'[^\001-~]' file.xml

La configuración LC_COLLATE=Cevita sorpresas desagradables sobre el significado de los rangos de caracteres en muchos lugares. La configuración LC_CTYPE=Ces necesaria para que coincida con caracteres de un solo byte; de ​​lo contrario, el comando omitiría secuencias de bytes no válidas en la codificación actual. La configuración LC_ALL=Cevita por completo los efectos dependientes de la ubicación.

Lo siguiente me funciona:

grep -P "[\x80-\xFF]" file.xml

Los caracteres que no son ASCII comienzan en 0x80 y llegan a 0xFF cuando se miran bytes. Grep (y su familia) no realizan procesamiento Unicode para fusionar caracteres de varios bytes en una sola entidad para la coincidencia de expresiones regulares como parece querer. La -Popción en my grep permite el uso de \xddescapes en clases de personajes para lograr lo que deseas.

Thelema avatar Jun 08 '2010 21:06 Thelema