Tengo algunos volcados de base de datos de un sistema Windows en mi caja. Son archivos de texto. Estoy usando cygwin para atravesarlos. Estos parecen ser archivos de texto sin formato; Los abro con editores de texto como el bloc de notas y el wordpad y se ven legibles. Sin embargo, cuando corro grep sobre ellos, dirá binary file foo.txt matches.
He notado que los archivos contienen algunos NULcaracteres ascii , que creo que son artefactos del volcado de la base de datos.
Entonces, ¿qué hace que grep considere que estos archivos son binarios? El NULpersonaje? ¿Hay una bandera en el sistema de archivos? ¿Qué necesito cambiar para que grep me muestre las coincidencias de línea?

--null-datapuede ser útil siNULes el delimitador.Respuestas:
Si hay un
NULcarácter en cualquier parte del archivo, grep lo considerará como un archivo binario.Puede haber una solución como esta
cat file | tr -d '\000' | yourgreppara eliminar todos los valores nulos primero y luego buscar a través del archivo.fuente
-a/--text, al menos con GNU grep.NUL(¿probablemente porque llama a printf de C y le da la línea coincidente?). En dicho sistemagrep cmd .sh_history, a devolverá tantas líneas vacías como líneas que coincidan con 'cmd', ya que cada línea de sh_history tiene un formato específico con unNULal comienzo de cada línea. (pero su comentario "al menos sobre GNU grep" probablemente se haga realidad. No tengo uno a mano en este momento para probar, pero espero que manejen esto muy bien)grepen cygwin consideraba binario porque tenía un guión largo (0x96) en lugar de un guión ASCII regular / menos (0x2d). Supongo que esta respuesta resolvió el problema del OP, pero parece que está incompleto.grep -atrabajó para mi:fuente
Puede utilizar la
stringsutilidad para extraer el contenido del texto de cualquier archivo y luego canalizarla a través degrep, por ejemplo:strings file | grep pattern.fuente
GNU grep 2.24 RTFS
Conclusión: solo 2 y 2 casos:
NUL, p.ejprintf 'a\0' | grep 'a'error de codificación según el C99
mbrlen(), por ejemplo:porque
\x80no puede ser el primer byte de un punto Unicode UTF-8 : UTF-8 - Descripción | en.wikipedia.orgAdemás, como lo menciona Stéphane Chazelas ¿Qué hace que grep considere que un archivo es binario? El | Unix y Linux Stack Exchange , esas comprobaciones solo se realizan hasta la primera lectura de búfer de longitud TODO.
Solo hasta la primera lectura del búfer
Por lo tanto, si se produce un error de codificación o NUL en el medio de un archivo muy grande, de todos modos podría aparecer grep.
Me imagino que esto es por razones de rendimiento.
Por ejemplo: esto imprime la línea:
pero esto no:
El tamaño real del búfer depende de cómo se lea el archivo. Por ejemplo, comparar:
Con el
sleep, la primera línea se pasa a grep incluso si solo tiene 1 byte porque el proceso se detiene, y la segunda lectura no comprueba si el archivo es binario.RTFS
Encuentre dónde está codificado el mensaje de error stderr:
Nos lleva a
/src/grep.c:Si esas variables estaban bien nombradas, básicamente llegamos a la conclusión.
encoding_error_output
Grepping rápido para
encoding_error_outputmuestra que la única ruta de código que puede modificarlo pasa porbuf_has_encoding_errors:entonces solo
man mbrlen.nlines_first_null y nlines
Inicializado como:
así que cuando se encuentra un nulo se
0 <= nlines_first_nullconvierte en verdad.TODO cuando puede
nlines_first_null < nlinesser falso? Me volví flojo.POSIX
No define las opciones binarias grep: busca en un archivo un patrón | pubs.opengroup.org , y GNU grep no lo documenta, por lo que RTFS es la única forma.
fuente
(printf '\n\0y') | grep ycon(printf '\n'; sleep 1; printf '\0y') | grep ypor ejemplo.export LC_CTYPE='en_US.UTF-8'que en mi ejemplo, o algo más? Buf read: ejemplo increíble, agregado a la respuesta. Obviamente has leído la fuente más que yo, me recuerda a esos hackers koans "El estudiante estaba iluminado" :-)Grep de repente vio uno de mis archivos de texto como binario:
La solución fue convertirlo usando
iconv:fuente
0xFChexadecimal, por lo que fuera del rango que grep esperaría para utf8 (hasta0x7F). Verifique con printf 'a \ x7F' | grep 'a' como Ciro describe arriba.El archivo
/etc/magico/usr/share/misc/magictiene una lista de secuencias que el comandofileusa para determinar el tipo de archivo.Tenga en cuenta que el binario puede ser una solución alternativa. A veces, los archivos con codificación extraña también se consideran binarios.
grepen Linux tiene algunas opciones para manejar archivos binarios como--binary-fileso-U / --binaryfuente
mbrlen(). Ejemplo e interpretación de la fuente en: unix.stackexchange.com/a/276028/32558Uno de mis alumnos tuvo este problema. Hay un error
grepenCygwin. Si el archivo tiene caracteres que no son Ascii,grepy véaloegrepcomo binario.fuente
En realidad, respondiendo a la pregunta "¿Qué hace que grep considere que un archivo es binario?", Puede usar
iconv:En mi caso, había caracteres españoles que aparecían correctamente en los editores de texto, pero grep los consideraba binarios;
iconvla salida me señaló los números de línea y columna de esos caracteresEn el caso de los
NULcaracteres,iconvlos considerará normales y no imprimirá ese tipo de salida, por lo que este método no es adecuado.fuente
Yo tuve el mismo problema. Solía
vi -b [filename]ver los caracteres añadidos. Encontré los personajes de control^@y^M. Luego, en vi escriba:1,$s/^@//gpara eliminar los^@caracteres. Repita este comando para^M.Advertencia: para obtener los caracteres de control "azules", presione Ctrl+ y vluego Ctrl+ Mo Ctrl+ @. Luego guardar y salir vi.
fuente