Estaba resolviendo un desafío donde encontré un archivo de datos sin extensión de archivo. El filecomando muestra que es un data file (application/octet-stream). El hdcomando muestra GNP. en la ultima linea. Entonces, si revierto este archivo, obtendré el archivo de formato .PNG , busqué en todas partes pero no encontré una solución que explicara cómo revertir el contenido de un archivo binario.
11

En
zsh(el único shell que puede manejar internamente datos binarios (a menos que desee considerar el enfoque de codificación base64 de ksh93 )):LC_ALL=C: los caracteres son bytes$mapfile[file.gnp]: contenido delfile.gnparchivos::: divide la cadena en sus componentes de bytesOa:Order inverso enasubíndice de matriz que matrizfuente
zshNo es el único shell que puede manejar datos binarios.Aquí hay una forma de invertir un archivo binario usando
ksh93. He dejado el código "suelto" para que sea más fácil de entender.fuente
readanterior no debería leer nada, ya que se hace al final del archivo.straceyksh93parece que se comporta de manera muy extraña, donde busca en todo el lugar dentro del archivo y lee grandes cantidades en ese momento. Quizás una variante de github.com/att/ast/issues/15straceel guión para ver a qué me refiero.ksh93lee los archivos miles de veces. Por ejemplo, antes de leer el primer byte, busca 64KiB al final del archivo, lee 64KiB, luego busca antes del último byte y lee 1 byte y hace algo similar para cada byte. Tenga en cuenta que lo que puede hacer con esas cadenas codificadas en base64 es limitado, por lo que si lee más de un byte a la vez, será más difícil extraer los bytes individuales de eso.Con perl:
Prueba de rendimiento:
Resultado:
perl -0777 -Fla más lenta.xxdes la más lenta.Nota: el tiempo de
diffejecución debe ser el mismo para todas las soluciones, ya que la salida debe ser la misma.fuente
perluno. En ese momento no me había dado cuenta de que tambiénreversepodía invertir las cadenas, por lo que hacer esa división no tenía mucho sentido y su versión es mucho mejor.Intenté lo siguiente:
La idea es forzar 'tac' usando cualquier carácter como separador. Lo intenté en un archivo binario y parecía funcionar, pero cualquier confirmación sería apreciada.
La principal ventaja es que no carga el archivo en la memoria.
fuente
tac8.28) cuando la entrada contiene caracteres de nueva línea.printf '1\n2' | tac -rs . | od -vAn -tcsalidas en\n 2 1lugar de2 \n 1. También necesitaríaLC_ALL=Co.podría coincidir con caracteres de varios bytes.LC_ALL=C tac -rs $'.\\|\n'parece funcionar sin embargo.