what files con regex unix unicode grep

regex - files - ¿Cómo grep para todos los caracteres que no son ASCII?



grep{} linux (10)

Tengo varios archivos XML muy grandes y estoy tratando de encontrar las líneas que contienen caracteres que no son ASCII. He intentado lo siguiente:

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

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

¿Tengo la sintaxis incorrecta o estoy haciendo otra cosa mal? También he intentado:

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

(con comillas simples y dobles alrededor del patrón).


Aquí hay otra variante que encontré que produjo resultados completamente diferentes de la búsqueda de grep para [/x80-/xFF] en la respuesta aceptada. Quizás le sea útil a alguien encontrar caracteres adicionales que no sean ascii:

grep --color=''auto'' -P -n "[^[:ascii:]]" myfile.txt

Nota: el grep de mi computadora (una Mac) no tenía la opción -P , así que ggrep brew install grep e inicié la llamada anterior con ggrep lugar de grep .


Curiosamente, tuve que hacer esto hoy! Terminé usando Perl porque no podía hacer que grep / egrep funcionara (incluso en el modo -P). Algo como:

cat blah | perl -en ''//xCA/xFE/xBA/xBE/ && print "found"''

Para caracteres Unicode (como /u2212 en el ejemplo a continuación) use esto:

find . ... -exec perl -CA -e ''$ARGV = @ARGV[0]; open IN, $ARGV; binmode(IN, ":utf8"); binmode(STDOUT, ":utf8"); while (<IN>) { next unless //N{U+2212}/; print "$ARGV: $&: $_"; exit }'' ''{}'' /;


El siguiente código funciona:

find /tmp | perl -ne ''print if /[^[:ascii:]]/''

Reemplace /tmp con el nombre del directorio que desea buscar.


En lugar de hacer suposiciones sobre el rango de bytes de los caracteres que no son ASCII, como lo hacen la mayoría de las soluciones anteriores, es IMO un poco mejor ser explícito sobre el rango de bytes real de los caracteres ASCII.

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

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

(que básicamente codicia para cualquier carácter fuera del rango ASCII hexadecimal: desde / x00 hasta / x7F)

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

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

¿Alguna ventaja o desventaja que alguien pueda pensar?


En perl

perl -ane ''{ if(m/[[:^ascii:]]/) { print } }'' fileName > newFile


La forma más fácil es definir un carácter no ASCII ... como un carácter que no es un carácter ASCII.

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

Añadir una pestaña después de la ^ si es necesario.

La configuración de LC_COLLATE=C evita sorpresas desagradables sobre el significado de los rangos de caracteres en muchos lugares. El ajuste LC_CTYPE=C es necesario para hacer coincidir los caracteres de un solo byte; de ​​lo contrario, el comando perdería las secuencias de bytes no válidas en la codificación actual. La configuración de LC_ALL=C evita por completo los efectos dependientes de la configuración regional.


Los siguientes trabajos para mí:

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

Los caracteres no ASCII comienzan en 0x80 y van a 0xFF cuando se miran los bytes. Grep (y la familia) no realizan el procesamiento Unicode para combinar caracteres de múltiples bytes en una sola entidad para la coincidencia de expresiones regulares como pareces querer. La opción -P en mi grep permite el uso de escapes de /xdd en clases de caracteres para lograr lo que deseas.


Podría ser interesante saber cómo buscar un personaje Unicode. Este comando puede ayudar. Solo necesitas conocer el código en UTF8.

grep -v $''/u200d''


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 grep por el inverso

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

Tenga en cuenta también que el bit importante es el indicador -P que equivale a --perl-regexp : así 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.


Buscando caracteres no imprimibles.

Estoy de acuerdo con Harvey anteriormente enterrado en los comentarios, a menudo es más útil buscar caracteres no imprimibles O es fácil pensar que no es ASCII cuando realmente debería estar pensando que no se puede imprimir. Harvey sugiere "usar esto:" [^ / n - ~] ". Agregar / r para archivos de texto DOS. Eso se traduce como" [^ / x0A / x020- / x07E] "y agregar / x0D para CR"

Además, agregar -c (mostrar el recuento de patrones coincidentes) a grep es útil cuando se buscan caracteres no imprimibles, ya que las cadenas coincidentes pueden desordenar el terminal.

Descubrí que agregar un rango de 0-8 y 0x0e-0x1f (al rango de 0x80-0xff) es un patrón útil. Esto excluye la TAB, CR y LF y uno o dos caracteres imprimibles poco comunes. Entonces, en mi humilde opinión, un patrón de grep bastante útil (aunque crudo) es ESTE:

grep -c -P -n "[/x00-/x08/x0E-/x1F/x80-/xFF]" *

Descompostura:

/x00-/x08 - non-printable control chars 0 - 7 decimal /x0E-/x1F - more non-printable control chars 14 - 31 decimal /x80-1xFF - non-printable chars > 128 decimal -c - print count of matching lines instead of lines -P - perl style regexps Instead of -c you may prefer to use -n (and optionally -b) or -l -n, --line-number -b, --byte-offset -l, --files-with-matches

Por ejemplo, un ejemplo práctico de uso, encontrar para grep todos los archivos en el directorio actual:

find . -type f -exec grep -c -P -n "[/x00-/x08/x0E-/x1F/x80-/xFF]" {} +

Es posible que desee ajustar el grep a veces. por ejemplo, el carácter BS (0x08 - retroceso) utilizado en algunos archivos imprimibles o para excluir VT (0x0B - pestaña vertical). Los caracteres BEL (0x07) y ESC (0x1B) también pueden considerarse imprimibles en algunos casos.

Non-Printable ASCII Chars ** marks PRINTABLE but CONTROL chars that is useful to exclude sometimes Dec Hex Ctrl Char description Dec Hex Ctrl Char description 0 00 ^@ NULL 16 10 ^P DATA LINK ESCAPE (DLE) 1 01 ^A START OF HEADING (SOH) 17 11 ^Q DEVICE CONTROL 1 (DC1) 2 02 ^B START OF TEXT (STX) 18 12 ^R DEVICE CONTROL 2 (DC2) 3 03 ^C END OF TEXT (ETX) 19 13 ^S DEVICE CONTROL 3 (DC3) 4 04 ^D END OF TRANSMISSION (EOT) 20 14 ^T DEVICE CONTROL 4 (DC4) 5 05 ^E END OF QUERY (ENQ) 21 15 ^U NEGATIVE ACKNOWLEDGEMENT (NAK) 6 06 ^F ACKNOWLEDGE (ACK) 22 16 ^V SYNCHRONIZE (SYN) 7 07 ^G BEEP (BEL) 23 17 ^W END OF TRANSMISSION BLOCK (ETB) 8 08 ^H BACKSPACE (BS)** 24 18 ^X CANCEL (CAN) 9 09 ^I HORIZONTAL TAB (HT)** 25 19 ^Y END OF MEDIUM (EM) 10 0A ^J LINE FEED (LF)** 26 1A ^Z SUBSTITUTE (SUB) 11 0B ^K VERTICAL TAB (VT)** 27 1B ^[ ESCAPE (ESC) 12 0C ^L FF (FORM FEED)** 28 1C ^/ FILE SEPARATOR (FS) RIGHT ARROW 13 0D ^M CR (CARRIAGE RETURN)** 29 1D ^] GROUP SEPARATOR (GS) LEFT ARROW 14 0E ^N SO (SHIFT OUT) 30 1E ^^ RECORD SEPARATOR (RS) UP ARROW 15 0F ^O SI (SHIFT IN) 31 1F ^_ UNIT SEPARATOR (US) DOWN ARROW