Eu preciso percorrer um diretório recursivamente e remover todos os arquivos com extensão .pdf
e .doc
. Estou conseguindo percorrer um diretório recursivamente, mas não consigo filtrar os arquivos com as extensões de arquivo mencionadas acima.
Meu código até agora
#/bin/sh
SEARCH_FOLDER="/tmp/*"
for f in $SEARCH_FOLDER
do
if [ -d "$f" ]
then
for ff in $f/*
do
echo "Processing $ff"
done
else
echo "Processing file $f"
fi
done
Preciso de ajuda para concluir o código, pois não estou chegando a lugar algum.
rm
faz parte do código do OP, mas na verdade não é relevante para a pergunta. Eu acho que seria mais seguro se as respostas fossem formuladas usando um comando inofensivo comoecho
.Respostas:
find
é feito apenas para isso.fonte
-delete
escolha a opção.find ... -print0 | xargs -0 ...
, não encontrar bruto | xargs para evitar problemas com nomes de arquivos que contêm novas linhas.xargs
sem opções quase sempre é um mau conselho e isso não é exceção. Use emfind … -exec
vez disso.Como acompanhamento da resposta do mouviciel, você também pode fazer isso como um loop for, em vez de usar xargs. Costumo achar xargs pesados, especialmente se precisar fazer algo mais complicado em cada iteração.
Como várias pessoas comentaram, isso falhará se houver espaços nos nomes de arquivos. Você pode contornar isso definindo temporariamente o IFS (separador de campo interno) para o caractere de nova linha. Isso também falha se houver caracteres curinga
\[?*
nos nomes dos arquivos. Você pode contornar isso desativando temporariamente a expansão de curinga (globbing).Se você tiver novas linhas em seus nomes de arquivos, isso também não funcionará. Você está melhor com uma solução baseada em xargs:
(Os colchetes de escape são necessários aqui para que as
-print0
duasor
cláusulas sejam aplicáveis ).O GNU e o * BSD find também têm uma
-delete
ação, que seria assim:fonte
for f in $(find ...)
. Só não use esse método.Sem
find
:/tmp/*
são arquivos em dir e/tmp/**/*
são arquivos em subpastas. É possível que você tenha que ativar a opção globstar (shopt -s globstar
). Portanto, para a pergunta, o código deve ficar assim:Observe que isso requer bash ≥4.0 (ou zsh sem
shopt -s globstar
ou ksh com emset -o globstar
vez deshopt -s globstar
). Além disso, no bash <4.3, isso percorre links simbólicos para diretórios e também para diretórios, o que geralmente não é desejável.fonte
for f in /tmp/**
será suficiente. Inclui os arquivos de / tmp dir.for f in /tmp/*.{pdf,doc} tmp/**/*.{,pdf,doc} ; do
**
é uma boa extensão, mas não é portátil para POSIXsh
. (Esta questão é marcado festa . Mas seria bom ressaltar que, diferentemente de várias das soluções aqui, este é realmente Bash-only Ou, bem, ele funciona em vários outros conchas prolongados, também.)Se você quiser fazer algo recursivamente, sugiro que você use recursão (sim, você pode fazê-lo usando pilhas e assim por diante, mas ei).
Dito isto,
find
é provavelmente uma escolha melhor, como já foi sugerido.fonte
Aqui está um exemplo usando shell (
bash
):fonte
Isso não responde diretamente à sua pergunta, mas você pode resolver o problema com uma única linha:
Algumas versões do find (GNU, BSD) têm uma
-delete
ação que você pode usar em vez de chamarrm
:fonte
Este método lida bem com os espaços.
Editar, corrige um por um
fonte
Para o bash (desde a versão 4.0):
Isso é tudo.
A extensão à direita ".ext" lá para selecionar arquivos (ou diretórios) com essa extensão.
A opção globstar ativa o ** (pesquisa recursivamente).
A opção nullglob remove um * quando não corresponde a nenhum arquivo / diretório.
A opção dotglob inclui arquivos que começam com um ponto (arquivos ocultos).
Cuidado antes do bash 4.3,
**/
também percorre links simbólicos para diretórios que não são desejáveis.fonte
A função a seguir iteraria recursivamente por todos os diretórios no
\home\ubuntu
diretório (toda a estrutura de diretórios no ubuntu) e aplicaria as verificações necessárias noelse
bloco.fonte
Esta é a maneira mais simples de fazer isso:
rm **/@(*.doc|*.pdf)
**
faz esse trabalho recursivamente@(*.doc|*.pdf)
procura um arquivo que termina em pdf OU docFácil de testar com segurança, substituindo
rm
porls
fonte
Não há razão para canalizar a saída
find
para outro utilitário.find
tem uma-delete
bandeira embutida nele.fonte
As outras respostas fornecidas não incluirão arquivos ou diretórios que começam com a. o seguinte funcionou para mim:
fonte
Apenas faça
fonte
O seguinte fará um loop pelo diretório fornecido recursivamente e listará todo o conteúdo:
for d in /home/ubuntu/*; do echo "listing contents of dir: $d"; ls -l $d/; done
fonte
ls -l /home/ubuntu/*/
, por isso é bastante inútil.Se você pode alterar o shell usado para executar o comando, pode usar o ZSH para fazer o trabalho.
Isso irá percorrer recursivamente todos os arquivos / pastas.
fonte