Como exibir as partes não esparsas de um arquivo esparso?

Como exibir as partes não esparsas de um arquivo esparso?

Imagine um arquivo criado com:

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

Agora tenho um arquivo de 2 tebibytes (que ocupa 4kiB no disco), "test\n"escrito no meio.

Como eu recuperaria isso de "test"forma eficiente, sem precisar ler o arquivo inteiro.

tr -d '\0' < file

Me daria o resultado, mas isso levaria horas.

O que eu gostaria é de algo que produza apenas as partes não esparsas do arquivo (acima apenas "test\n"ou mais provavelmente, o bloco de 4kiB alocado no disco que armazena esses dados).

Existem APIs para descobrir quais partes do arquivo estãoalocado(FIBMAP, FIEMAP, SEEK_HOLE, SEEK_DATA...), mas quais ferramentas os expõem?

Uma solução portátil (pelo menos para os sistemas operacionais que suportam essas APIs) seria apreciada.

Responder1

O melhor que consegui até agora é (ksh93, usando filefrag1.42.9 e2fsprogs(algumas versões mais antigas têm uma API diferente), em sistemas de arquivos baseados em extensão no 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

filefragrelata as extensões do arquivo usando o ioctl FIEMAP para os sistemas de arquivos que o suportam.

A *unwritten*parte cobre os arquivos (não esparsos, mas ainda cheios de zeros nos quais não estou interessado) que foram gravados, fallocatedmas não foram gravados.

Versões recentes bsdtarou starpodem usar algumas dessas APIs para gerar um tararquivo que identifica as seções esparsas como tal. Isso daria maisportátilsolução, mas seria necessário analisar o arquivo tar gerado para obter as seções não esparsas.

informação relacionada