
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' or
ações -execdir', pois evita totalmente a sobrecarga de bifurcar um novo processo e usarexec' to run
/bin/rm'. Também é normalmente mais eficiente do quexargs' for the same reason. The file deletion is performed from the directory containing the entry to be deleted, so the
a 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 -delete
implica também o switch -depth
. O que isto significa? Aqui está um exemplo de como -delete
você 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 -delete
inclui uma -depth
opçã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 -delete
mé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 ... -print0
irá construir uma lista de arquivos que correspondem aos critérios especificados. Essa lista é então passada pelo canal para xargs
. A -print0
opção coloca um caractere ASCII NUL como separador entre cada resultado da localização. A -0
ativação xargs
faz 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 -print0
opçã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 rm
comando para cada arquivo individual que o find
comando 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 /etc
diretório em /var/tmp/somedir
. Quando o comando acima for executado, o /etc
diretório também será excluído. Este problema existe com qualquer um dos métodos de exclusão de arquivos, exceto a -delete
opçã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 -0
pode ser semelhante em desempenho, mas não é tão seguro. A -delete
açã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 find
eBDS find
nãosiga links simbólicos, a menos que seja usado um -L
sinalizador 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 find
para seguir links virtuais usando a -L
bandeira. Esta é a escolha perigosa, de qualquer maneira.
Para links físicos, find
seguiremos o link paraoutro arquivomas observe que o link direto para umoutro diretório"provavelmente falhará" como visto man ln
no 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 find
não haverá nada para seguir.
Observe que algumas ln
implementações de BDS não têm -d
nenhuma opção.