Tengo problemas con un archivo de texto marcado como binario

3

Tengo un ejecutable que genera un archivo de texto como salida. El problema es que el archivo de texto sale con un indicador de archivo binario de algún tipo. El resultado es algo como esto:

$ grep "grep string" output_file.txt
Binary file output_file.txt matches.

$ grep -a "grep string" output_file.txt
[correct results]

Algunas lecturas han indicado que grep busca un carácter nulo en los primeros mil bytes, luego determina si un archivo es 'binario' o no, por lo que mi pregunta es doble:

  1. ¿Hay una manera fácil de quitar caracteres nulos de mis archivos (puedo hacer esto como parte de mi postprocesamiento) para asegurar que grep funcione correctamente sin la bandera -a?

  2. ¿Hay algo obvio que debería buscar en mi código para evitar que se escriban caracteres nulos en el archivo? He revisado el código completamente y no veo ningún culpable obvio.

    .

brightwellcd
fuente

Respuestas:

5

Puedo responder al menos la primera pregunta. Si usa Unix / Linux, puede usar tr

tr -d '\000' < filein > fileout

donde \ 000 es el carácter nulo. También puede quitar todos los caracteres no imprimibles como puede ver en el ejemplo aquí: "Edición de texto Unix: sed, tr, cut, od, awk"

Con respecto a su segunda pregunta, no sé cuál es su lenguaje de programación, pero buscaría variables no inicializadas que podrían imprimirse en el archivo de salida.

DrNoone
fuente
Votaría esto si pudiera, pero aparentemente soy demasiado nuevo. : - /
brightwellcd
Encontré una cadena nula en mi salida. Ejecuté este script tr e hice una diferencia visual; Rápidamente encontró el problema. Voy a votar esto si tengo la reputación suficiente para hacerlo. Gracias.
brightwellcd
4

Voy a adivinar ...

Su programa escribe el archivo en UTF-16, una codificación de Unicode que usa dos bytes para cada carácter. Cada segundo byte es, la mayoría de las veces, un valor nulo.

iconv -f utf-16 -t utf-8 < filein > fileout

lo convertirá a UTF-8, con el que la mayoría de los coreutils se sienten cómodos.

Gravedad
fuente
Interesante, y no sabía esto sobre UTF-16. Una pregunta sobre este comando: ¿qué elimina o hace la conversación exactamente al archivo? ¿Cómo se comportará en el caso de uso de mi pregunta aquí ?
Hashim
1
@Hashim: no elimina nada; lee valores en una representación y escribe los mismos valores en otra. (Al igual que la conversión entre hexadecimal y octal, o entre PNG y BMP). UTF-16 representa cada valor de punto de código como un código de dos bytes de longitud fija (o un par de dos códigos de este tipo), que naturalmente debe rellenarse con un 0x00 bytes si el valor es inferior a 256, mientras que UTF-8 representa el mismo valor que un código de longitud variable que no requiere relleno nulo. Cómo se comportará con su archivo depende de si su archivo es UTF-16 para empezar.
Grawity
@Hashim ¿Hay alguna forma de determinar si un archivo es UTF-16? Hacer file myfile.txtsimplemente muestra el archivo como data.
Hashim
Si es texto y parece texto en su editor de texto, observe qué codificación ha detectado el editor. Intente realizar la conversión y verifique si el resultado todavía se ve como texto en su editor de texto. O haga un volcado hexadecimal de su archivo, si ve que "cada segundo byte" es 0x00, eso casi siempre significa UTF-16.
Grawity
Desafortunadamente, abrir el archivo en un editor está fuera de discusión ya que los archivos en los que estoy trabajando son demasiado grandes, todos más de 10 GB. Si no hay bytes NUL en la segunda columna de un hexdump, ¿es seguro concluir que el archivo definitivamente no es UTF-16?
Hashim