exclusão em massa de arquivo

exclusão em massa de arquivo

Gostaria de excluir todos os arquivos txt, xls, pdf de um diretório, bem como seus subdiretórios. Eu gostaria de salvar todo o resto.

find . -type f ! -iname '*.xml$,.png$,.jpeg$,.gif$,' -delete

isso parecia ter acontecido, mas excluiu alguns outros arquivos que eu preciso. Como posso conseguir isso sem excluir mais nada?

Responder1

Em vez disso, faça isso:

find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -delete

Você também pode usar expressões regulares:

find . -type f -iregex '.*\.\(xml\|png\|jpeg\|gif\)$' -delete

Responder2

Existem basicamente 4 maneiras de abordar esse problema usando find.

Método #1 - usando-delete

$ find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -delete

Como outros mencionaram nestas perguntas e respostas, este método é o mais rápido e que consome menos recursos. Citando doencontrar documentos on-line:

10.1.6 Usando a ação `-delete'


O método mais eficiente e seguro de resolver este problema é usar a ação `-delete':

 find /var/tmp/stuff -mtime +90 -delete

Esta alternativa é mais eficiente do que qualquer uma das -exec' orações -execdir', pois evita totalmente a sobrecarga de bifurcar um novo processo e usar exec' to run/bin/rm'. Também é normalmente mais eficiente do que xargs' for the same reason. The file deletion is performed from the directory containing the entry to be deleted, so thea ação -delete' e tem as mesmas vantagens de segurança que a ação `-execdir'.

A ação `-delete' foi introduzida pela família de sistemas operacionais BSD.

OBSERVAÇÃO:Uma coisa a ter em mente com esta abordagem é que o uso de -deleteimplica também o switch -depth. O que isto significa? Aqui está um exemplo de como -deletevocê pode queimar se não tomar cuidado.

Por exemplo, digamos que eu tenha um diretório de trabalho do Subversion onde desejo limpar alguns arquivos, mas deixar seus subdiretórios .svn intactos. Eu poderia usar o seguinte comando para fazer isso:

$ find . -not "(" -name .svn -type d -prune ")" -type f -print
./a.txt

Mas como -deleteinclui uma -depthopção, os arquivos que realmente seriam tratados:

$ find . -not "(" -name .svn -type d -prune ")" -type f -print -depth
./.svn/all-wcprops
./.svn/entries
./.svn/format
./.svn/text-base/a.txt.svn-base
./a.txt

Por esse motivo, ao usar -delete, é preciso ter cuidado.

Método #2 --exec command {} +

$ find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -exec rm {} \+

Comparado ao -deletemétodo, esta é provavelmente a próxima melhor opção, em termos de desempenho e portabilidade entre Unixes. A -exec ... {} +notação funciona da seguinte maneira:

da página de manual de localização

Esta variante da ação -exec executa o comando especificado nos arquivos selecionados, mas a linha de comando é construída anexando cada nome de arquivo selecionado no final; o número total de invocações do comando será muito menor que o número de arquivos correspondentes. A linha de comando é construída da mesma maneira que o xargs constrói suas linhas de comando. Apenas uma instância de `{}' é permitida no comando. O comando é executado no diretório inicial.

Portanto, na verdade, esse método funciona de maneira semelhante a xargs, mas sem a necessidade de passar por obstáculos para passar a saída de um find através de um canal para xargs.

Método #3 -xargs

$ find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -print0 | xargs -0 rm -f

O find ... -print0irá construir uma lista de arquivos que correspondem aos critérios especificados. Essa lista é então passada pelo canal para xargs. A -print0opção coloca um caractere ASCII NUL como separador entre cada resultado da localização. A -0ativação xargsfaz com que os arquivos transmitidos sejam separados por caracteres ASCII NUL.

Comparado aos métodos nº 1 e nº 2, este terá desempenho semelhante ao nº 2, porém a -print0opção não é universalmente suportada em todos os Unixes.

Método #4 --exec command {} \;

$ find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' | exec rm -f {} \;

Comparado com os três primeiros métodos, este é o de menor desempenho. Ele literalmente chama o rmcomando para cada arquivo individual que o findcomando encontra.

Considerações adicionais sobre segurança

Uma coisa que pode não ser tão óbvia ao usar qualquer um dos métodos acima é que alguns métodos são mais seguros que outros. Você provavelmente está dizendo a si mesmo:... segurança? .. o que? Aqui está um exemplo.

Assuma seu root e execute o seguinte comando:

$ find /var/tmp/somedir -type f -exec rm {} \;

Sem que você saiba, alguém criou maliciosamente um link para o /etcdiretório em /var/tmp/somedir. Quando o comando acima for executado, o /etcdiretório também será excluído. Este problema existe com qualquer um dos métodos de exclusão de arquivos, exceto a -deleteopção (método nº 1).

dr;

A maneira mais rápida e segura de excluir arquivos com a ajuda do find é usar -delete. O uso xargs -0pode ser semelhante em desempenho, mas não é tão seguro. A -deleteação não é totalmente portátil. A alternativa portátil mais eficiente é -exec ... +, mas é insegura e não é suportada por versões do GNU findutils anteriores a 4.2.12.

Referências

Responder3

Há uma ligeira imprecisãoresposta.

NOTA e Isenção de responsabilidade: isso tem que ser um comentário pararespostamas no momento não posso fazer comentários ainda.

O exemplo "alguém criou um link maliciosamente" dado emConsiderações adicionais sobre segurançanão é totalmente preciso tanto sobre links físicos Unix quanto para links virtuais Unix.

Para entender a diferença entre os dois, consulteLink físico e links simbólicos no Unixou pesquise no Google.

Para soft links (o tipo mais usado de qualquer maneira) ambos GNU findeBDS find nãosiga links simbólicos, a menos que seja usado um -Lsinalizador específico para forçar o seguimento de links simbólicos. [Ver man find]

Portanto, este exemplo provavelmente não será um problema, a menos que vocêforça findpara seguir links virtuais usando a -Lbandeira. Esta é a escolha perigosa, de qualquer maneira.

Para links físicos, findseguiremos o link paraoutro arquivomas observe que o link direto para umoutro diretório"provavelmente falhará" como visto man lnno GNU ln:

   -d, -F, --directory
          allow the superuser to attempt to hard link directories (note: will probably
          fail due to system restrictions, even for the superuser)

Portanto, provavelmente é impossível criar o link físico para um diretório e findnão haverá nada para seguir.

Observe que algumas lnimplementações de BDS não têm -dnenhuma opção.

informação relacionada