¿Cómo mostrar las partes no dispersas de un archivo disperso?

8

Imagine un archivo creado con:

truncate -s1T file
echo test >> file
truncate -s2T file

Ahora tengo un archivo de 2 tebibytes (que ocupa 4 KB en el disco), con "test\n"escrito en el medio.

¿Cómo lo recuperaría de manera "test"eficiente, sin tener que leer todo el archivo?

tr -d '\0' < file

Me daría el resultado, pero eso llevaría horas.

Lo que me gustaría es algo que solo muestre las partes no dispersas del archivo (por lo tanto, solo arriba "test\n"o más probablemente, el bloque 4kiB asignado en el disco que almacena esos datos).

Hay API para averiguar qué parte del archivo está asignada (FIBMAP, FIEMAP, SEEK_HOLE, SEEK_DATA ...), pero ¿qué herramientas las exponen?

Se agradecería una solución portátil (al menos para los sistemas operativos que admiten esas API).

Stéphane Chazelas
fuente
¿Qué tan eficiente es strings?
Glenn Jackman
@glennjackman, menos que trdesde que todavía lee todo el archivo y hace más que solo eliminar los bytes NUL.
Stéphane Chazelas

Respuestas:

6

Lo mejor que podía llegar a hasta el momento es (ksh93, utilizando filefragdesde e2fsprogs1.42.9 (algunas versiones anteriores tienen un API diferente), en sistemas de archivos basados medida de Linux):

#! /bin/ksh93
export LC_ALL=C
for file do
filefrag -vb1 -- "$file" |
  while IFS=": ." read -A a; do
    [[ $a = +([0-9]) ]] && [[ ${a[@]} != *unwritten* ]] &&
      command /opt/ast/bin/head -s "${a[1]}" -c "${a[7]}" -- "$file"
  done
done

filefrag informa sobre la extensión del archivo utilizando FIEMAP ioctl para los sistemas de archivos que lo admiten.

La *unwritten*parte cubre los archivos (no dispersos, pero todavía llenos de ceros que no me interesan) que se han fallocatedescrito pero no se han escrito.

Las versiones recientes de bsdtaro starpueden usar algunas de esas API para generar un tararchivo que identifica las secciones dispersas como tales. Eso sería una solución más portátil , pero luego uno tendría que analizar el archivo tar generado para obtener las secciones no dispersas.

Stéphane Chazelas
fuente