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
Eu gostaria de excluir todos os arquivos txt, xls, pdf em um diretório, assim como seus subdiretórios. Eu gostaria de salvar todo o resto.
find . -type f ! -iname '*.xml$,.png$,.jpeg$,.gif$,' -delete
que parece ter feito isso, mas exclui alguns outros arquivos que eu preciso. Como posso conseguir isso sem excluir mais nada?
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
Existem basicamente 4 maneiras de abordar esse problema usando o find.
-delete
$ find . -type f -iname '*.xml' -o -iname '*.png'\
-o -iname '*.jpeg' -o -iname '*.gif' -delete
Como outros mencionaram neste Q & A, esse método é o mais rápido e o de menor uso intensivo de recursos. Citando os documentos on-line :
10.1.6 Using the '-delete' action
The most efficient and secure method of solving this problem is to use the '-delete' action:
find /var/tmp/stuff -mtime +90 -delete
This alternative is more efficient than any of the
-exec' or
-execdir' actions, since it entirely avoids the overhead of forking a new process and usingexec' to run
/bin/rm'. It is also normally more efficient thanxargs' for the same reason. The file deletion is performed from the directory containing the entry to be deleted, so the
-delete' action has the same security advantages as the '-execdir' action has.The '-delete' action was introduced by the BSD family of operating systems.
OBSERVAÇÃO: Uma coisa a ter em mente com esta abordagem, o uso de -delete
implica também a opção -depth
. O que isto significa? Aqui está um exemplo de como -delete
pode queimar você se você não for cuidadoso.
Por exemplo, digamos que eu tenha um diretório de trabalho de subversão onde eu queira limpar alguns arquivos, mas deixe seus subdiretórios .svn intactos. Eu poderia usar o seguinte comando para realizar isso:
$ find . -not "(" -name .svn -type d -prune ")" -type f -print
./a.txt
Mas como -delete
inclui uma opção -depth
, os arquivos que seriam realmente 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.
-exec command {} +
$ find . -type f -iname '*.xml' -o -iname '*.png'\
-o -iname '*.jpeg' -o -iname '*.gif' -exec rm {} \+
Em comparação com o método -delete
, esta é provavelmente a melhor opção seguinte, em termos de desempenho & portabilidade entre Unixes. A notação -exec ... {} +
funciona da seguinte maneira:
da página man do encontro
This variant of the -exec action runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invocations of the command will be much less than the number of matched files. The command line is built in much the same way that xargs builds its command lines. Only one instance of '{}' is allowed within the command. The command is executed in the starting directory.
Portanto, na verdade, esse método funciona de forma semelhante a xargs
, mas sem ter que passar por obstáculos de passar a saída de uma descoberta por meio de um canal para xargs
.
xargs
$ find . -type f -iname '*.xml' -o -iname '*.png'\
-o -iname '*.jpeg' -o -iname '*.gif' -print0 | xargs -0 rm -f
O find ... -print0
criará uma lista de arquivos correspondentes aos critérios especificados. Essa lista é então passada pelo pipe para xargs
. A opção -print0
coloca um caractere ASCII NUL como um separador entre cada resultado de find. A opção -0
em xargs
faz supor que os arquivos que estão sendo passados são separados por caracteres ASCII NUL.
Em comparação com os métodos # 1 e amp; # 2, este terá um desempenho semelhante ao # 2, no entanto, a opção -print0
não é universalmente suportada em todos os Unixes.
-exec command {} \;
$ find . -type f -iname '*.xml' -o -iname '*.png'\
-o -iname '*.jpeg' -o -iname '*.gif' | exec rm -f {} \;
Em comparação com os 3 primeiros métodos, este é o de menor desempenho. Chama literalmente o comando rm
para cada arquivo individual que o comando find
encontra.
Uma coisa que pode não ser tão óbvia ao usar qualquer um dos métodos acima é que alguns dos métodos são mais seguros do que os outros. Você provavelmente está dizendo para si mesmo ... segurança? .. que? Aqui está um exemplo.
Assuma sua raiz e execute o seguinte comando:
$ find /var/tmp/somedir -type f -exec rm {} \;
Sem o seu conhecimento, alguém criou maliciosamente um link para o diretório /etc
em /var/tmp/somedir
. Quando o comando acima for executado, o diretório /etc
também será excluído. Esse problema existe com qualquer um dos métodos para excluir arquivos, exceto a opção -delete
(método 1).
A maneira mais rápida e segura de excluir arquivos com a ajuda do find é usar -delete
. Usar xargs -0
pode ser semelhante em desempenho, mas não é tão seguro. A ação -delete
não é totalmente portátil. A alternativa portátil mais eficiente é -exec ... +
, mas isso é inseguro e não é suportado por versões de findutils do GNU anteriores a 4.2.12.
Existe uma pequena imprecisão na resposta do slm .
NOTA & Disclamer : este deve ser um comentário para resposta do slm , mas agora eu não posso fazer comentários ainda.
O exemplo "alguém criou maliciosamente um link" fornecido em Considerações adicionais sobre segurança não é totalmente preciso sobre links físicos Unix e links para Unix.
Para entender a diferença entre os dois, consulte link físico e links simbólicos em Unix ou pesquise no Google.
Para links suaves (o tipo mais usado de qualquer maneira), ambos GNU find
e BDS find
não seguem links simbólicos, a menos que seja usado um sinalizador específico -L
para forçar o link simbólico a seguir. [Veja man find
]
Portanto, este exemplo provavelmente não será um problema, a menos que você force find
a seguir os soft links usando o -L
flag. Esta é a escolha perigosa, de qualquer maneira.
Para os links físicos, find
seguirá o link para outro arquivo , mas observe que o link físico para um outro diretório "provavelmente falhará", conforme veremos em man ln
para o% GNUln
:
-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 terá nada a seguir.
Observe que alguns BDS ln
implementação não tem uma -d
opção.