Exclui todos, exceto 1000 arquivos aleatórios em um diretório

9

Eu deixo um script de geração de dados rodar muito agora tenho 200.000+ arquivos que eu preciso reduzir para cerca de 1000. Na linha de comando do Linux, existe uma maneira fácil de deletar todos, menos 1000 desses arquivos, onde os arquivos que seria retido não teria dependência no nome do arquivo ou qualquer outro atributo?

    
por Malcolm Regan 08.03.2017 / 02:11

3 respostas

9

Excluir todos os arquivos aleatórios, exceto 1000, em um diretório

Código:

find /path/to/dir -type f -print0 | sort -zR | tail -zn +1001 | xargs -0 rm

Explicação:

  1. Listar todos os arquivos em /path/to/dir com find ;
    • print0 : use sort ( caractere nulo ) como o delimitador de linha; então caminhos de arquivo contendo espaços / novas linhas não quebram o script
  2. Embaralhe a lista de arquivos com -z ;
    • \n : use -R (caractere nulo) como delimitador, em vez de tail (uma nova linha)
    • -z : ordem aleatória
  3. Retire as primeiras 1000 linhas da lista aleatória com sort ;
    • -n +1001 : trata a lista como delimitada por zero (igual a com xargs -0 rm )
    • -0 : mostra as linhas a partir de 1001 (ou seja, omite as primeiras 1000 linhas)
  4. find - remove os arquivos restantes;
    • find : delimitado por zero, novamente

Por que é melhor do que a solução da quixotic *:

  1. Funciona com nomes de arquivos contendo espaços / novas linhas.
  2. Não tenta criar nenhum diretório (que já pode existir, btw.)
  3. Não move nenhum arquivo, nem sequer toca nos 1000 "arquivos da sorte", além de listá-los com \n .
  4. Evita perder um arquivo caso a saída de | sort -R | head -1000 não termine com %code% (nova linha) por algum motivo.

* - crédito para quixotic por %code% , me deu um ponto de partida.

    
por 08.03.2017 / 07:04
1

Use um diretório temporário, em seguida, find de todos os seus arquivos, randomize a lista com sort e mova os 1000 principais da lista para o diretório temporário. Exclua o restante e mova os arquivos de volta do diretório temporário.

$ mkdir ../tmp-dir
$ find . -type f | sort -R | head -1000 | xargs -I "I" mv I ../tmp-dir/
$ rm ./*
$ mv ../tmp-dir/* .

Se xargs reclamar sobre o tamanho da linha, use um número menor com head e repita o comando conforme necessário (ou seja, altere -1000 para -500 e execute-o duas vezes ou altere para -200 e execute 5 vezes.)

Também falhará ao lidar com nomes de arquivos que incluam espaços; como mostra a @ resposta do rld , você pode usar o argumento find -print0 , os argumentos -z para sort e head e -0 com xargs para garantir o manuseio adequado dos arquivos.

Finalmente, se o tmp-dir já existir, você deve substituir um nome de diretório que não existe.

    
por 08.03.2017 / 03:50
-2

O mais fácil pode ser rm -rf o diretório e, em seguida, executar novamente o script de geração de dados, certificando-se de não executar por muito tempo.

    
por 08.03.2017 / 03:15

Tags