
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 filefrag
desde e2fsprogs
1.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
filefrag
informa 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 fallocated
no se ha escrito.
Las versiones recientes de bsdtar
o star
pueden usar algunas de esas API para generar un tar
archivo 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.