Exclua arquivos e diretórios pelos seus nomes. Não existe tal arquivo ou diretório

28

Eu preciso excluir todos os dados compilados:

  • diretórios chamados build ,
  • diretórios chamados obj ,
  • *. so arquivos.

Eu escrevi um comando

find \( -name build -o -name obj -o -name *.so \) -exec rm -rf {} \;

que percorre todos os diretórios de forma recursiva e exclui tudo o que preciso.

Por que eu tenho essa saída no final? Talvez eu deva escrever um comando diferente.

find: './3/obj': No such file or directory
find: './3/build': No such file or directory
find: './1/obj': No such file or directory
find: './1/build': No such file or directory
find: './2/obj': No such file or directory
find: './2/build': No such file or directory
    
por Maksim Dmitriev 19.02.2014 / 10:04

3 respostas

47

Use -prune nos diretórios que você irá excluir de qualquer forma para informar find para não tentar encontrar arquivos neles:

find . \( -name build -o -name obj -o -name '*.so' \) -prune -exec rm -rf {} +

Observe também que *.so precisa ser citado, caso contrário, pode ser expandido pelo shell para a lista de .so arquivos no diretório atual.

O equivalente do seu% GNU-regex -type seria:

find . \( -name build -o -name obj -o -name '*?.so' \) -prune -exec rm -rf {} +

Observe que, se você usar a sintaxe específica do GNU, também poderá usar -delete em vez de -exec rm -rf {} + . Com -delete , o% GNUfind ativa -depth automaticamente. Ele não executa comandos externos então, dessa forma, é mais eficiente, e também é mais seguro pois remove a condição de corrida onde alguém pode fazer com que você remova os arquivos errados alterando um diretório para um symlink entre as horas find encontra um arquivo e rm o remove (veja info -f find -n 'Security Considerations for find' para detalhes).

find . -regextype posix-egrep -regex '.*/((obj|build)(/.*)?|.+\.so)' -delete
    
por 19.02.2014 / 10:43
8

Eu acho que a razão é que find apaga a árvore de diretórios primeiro e tenta verificar o conteúdo do diretório que obviamente não é a melhor ordem possível. Você pode forçar o find a verificar o conteúdo primeiro:

find . -depth ...

Você deve considerar o uso de -delete para arquivos e -exec rmdir para diretórios.

    
por 19.02.2014 / 10:25
0

Minha solução.

find . -regextype posix-egrep -regex ".*/(obj|build|.+\.so)" -prune -exec rm -rf {} +

+ vs \; no comando -exec

    
por 19.02.2014 / 12:18