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

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

Imagine un archivo creado con:

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

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

¿Cómo podría recuperarlo de manera tan "test"eficiente, es decir, sin tener que leer el archivo completo?

tr -d '\0' < file

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

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

Hay API para saber qué parte del archivo estáasignado(FIBMAP, FIEMAP, SEEK_HOLE, SEEK_DATA...), pero ¿qué herramientas los exponen?

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

Respuesta1

Lo mejor que se me ocurrió hasta ahora es (ksh93, usado filefragdesde e2fsprogs1.42.9 (algunas versiones anteriores tienen una API diferente), en sistemas de archivos basados ​​en extensión en 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

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

La *unwritten*parte cubre los archivos (no escasos, pero aún llenos de ceros que no me interesan) en los que fallocatedno se ha escrito.

Las versiones recientes de bsdtaro starpueden usar algunas de esas API para generar un tararchivo que identifique las secciones dispersas como tales. Eso haría que fuera másportátilsolución, pero entonces habría que analizar el archivo tar generado para obtener las secciones no dispersas.

información relacionada