Encontre arquivos / diretórios mais antigos no sistema de arquivos de até 50 TB

8

Preciso encontrar os arquivos mais antigos com seus diretórios associados em um sistema de arquivos de 90 TB até 50 TB e depois movê-los para outro sistema de arquivos. Eles precisam manter sua estrutura de diretórios, pois é isso que identifica quais são os arquivos. Assim -

primeiro nível / segundo nível / terceiro nível / (arquivo)

é a estrutura. Preciso mover toda a estrutura - não há nada nos diretórios de nível superior, mas sem eles não consigo identificar ao que o arquivo pertence, pois todos os arquivos que estou procurando têm o mesmo nome. Quando o processo estiver concluído, eu devo ter aproximadamente 40 TB no sistema de arquivos original e quase nada no novo sistema de arquivos, já que os arquivos mais antigos do original já estão lá.

Obrigado!

J Telep
fonte

Respostas:

9

Com as ferramentas GNU e rsync, você pode fazer:

export LC_ALL=C # force tools to regard those file paths as arrays
                # of bytes (as they are in effect) and not do fancy
                # sorting (and use English for error/warning messages 
                # as an undesired side effect).

find . -type f -printf '%T@/%s/%p\0' | # print mtime/size/path
  sort -zn | # numerical sort, oldest first
  awk -v RS='\0' -v ORS='\0' -F / -v max=50e12 '
    {total_size += $2}
    total_size > max {exit}
    {
      sub("^[^/]*/[^/]*/", "") # remove mtime/size/
      print # path
    }' |
  rsync -nv -aHAX0 --files-from=- --remove-source-files . /dest/dir/

(não testado. -nÉ para uso a seco. Remova se estiver feliz).

Observe que estamos calculando o tamanho acumulado do arquivo com base nos tamanhos dos arquivos ( %ssubstitua %bpelo uso do disco nos setores (e mude para total_size += $2 * 512) e ignorando os links físicos. Esses arquivos, quando copiados para o sistema de arquivos de destino, juntamente com os diretórios que os contenham provavelmente acabará usando mais de 50 TB (a menos que haja compactação ou desduplicação do sistema de arquivos em execução).

Stéphane Chazelas
fonte
1
Resposta melhor resposta do que a minha (embora eu teria adicionado um total_size > max { exit 0 }para o script awk)
symcbean
@symcbean, bom ponto! Eu adicionei agora. Obrigado.
Stéphane Chazelas
Isso parece ótimo! Uma pergunta é: estou assumindo que a parte "max = 50e12" da declaração awk está ditando ao sistema que queremos 50 TB, com base em pastas extras (pois existem duas para cada arquivo), se eu precisasse reduzir que "50" a "49" e isso seria igual a 49 TB?
precisa
1
@JTelep, isso é notação científica. 50e12 é 50 vezes 10 à potência de 12, então 50TB (não 50TiB, para o qual você precisaria 50 * 2^40). Você também pode alterá-lo para total_size += $2 + overheadonde overheadé definido como a sobrecarga incorrida por essas pastas. Veja também em %kvez de %sobter o uso do disco no KiB.
Stéphane Chazelas
2

O comando 'ls' é um pouco criativo com registros de data e hora - portanto, analisá-los pode ser uma dor. Provavelmente seria muito mais fácil implementar isso em uma linguagem que implementa stat (). Algumas versões do Unix têm uma estatística de linha de comando - em uma caixa RH próxima:

 find ${BASEDIR} -type f -exec stat --format="%y %b %n" {} \; | sort | less

Mas isso funcionará como um cachorro com um grande número de arquivos.

A documentação do GNU awk inclui uma extensão de exemplo que fornece funções do sistema de arquivos, mas você precisaria fazer algum trabalho para criar e manter isso.

Escrever um programa a partir do zero em PHP, C ou Perl (ou ir, ruby ​​ou muitas outras linguagens) seria simples, mas fora do escopo de uma publicação aqui.

symcbean
fonte
1
Note que o GNU statfoi adicionado muito tempo depois do GNU findter um -printfcomando (que pode fazer o mesmo que o GNU statcom uma interface muito melhor).
Stéphane Chazelas 13/03/19