Como excluo recursivamente diretórios com curinga?

52

Estou trabalhando no SSH no WD My Book World Edition. Basicamente, gostaria de começar em um nível de diretório específico e remover recursivamente todos os subdiretórios correspondentes .Apple*. Como eu faria isso?

eu tentei

rm -rf .Apple* e rm -fR .Apple*

nem diretórios excluídos que correspondam a esse nome nos subdiretórios.

codedog
fonte

Respostas:

73

find é muito útil para executar ações seletivamente em uma árvore inteira.

find . -type f -name ".Apple*" -delete

Aqui, o -type fcertifica-se de que é um arquivo, não um diretório, e pode não ser exatamente o que você deseja, pois também ignorará links simbólicos, soquetes e outras coisas. Você pode usar ! -type d, o que literalmente significa não diretórios, mas também pode excluir caracteres e bloquear dispositivos. Eu sugiro olhar para o -typepredicado na página de manual find.

Para fazer isso estritamente com um curinga, você precisa de suporte avançado ao shell. O Bash v4 tem a globstaropção , que permite corresponder recursivamente subdiretórios usando **. zshe kshtambém suporta esse padrão. Usando isso, você pode fazer rm -rf **/.Apple*. Como o POSIX não é padrão e não é muito portátil, evitaria usá-lo em um script, mas para uma ação de shell interativa única, tudo bem.

Shawn J. Goff
fonte
3
Eu posso começar find . -type d -name .Apple*a trabalhar - ele lista todas as pastas. No entanto, falha quando adiciono -deleteno final. Ele volta com o resumo de uso. Está sendo executado no BusyBox v1.1.1. Isso faz alguma diferença?
Codedog
11
-deletetambém não é POSIX. **foi introduzido zshno início dos anos 90. É agora (por ordem cronológica de aparência) também em ksh93, fish, bash e tcsh.
Stéphane Chazelas
11
+1 pararm -rf **/.Apple*
Andriy Boyko
11
@ codedog, se -deletenão funcionar, use em seu -exec rm -f {} +lugar.
Curinga
11
Você pode findser detalhado ao excluir? Suponho que o método "globstar" faria isso adicionando a -vopção.
Demis
17

Eu tive problemas usando findcom -deletedevido ao comportamento intencional de find(ou seja, recusando-se a excluir se o caminho começar com ./, o que eles fazem no meu caso), conforme declarado em sua página de manual:

 -delete

Exclua os arquivos e / ou diretórios encontrados. Sempre retorna verdadeiro. Isso é executado a partir do diretório de trabalho atual, à medida que a localização se repete na árvore. Ele não tentará excluir um nome de arquivo com um caractere "/" em seu nome de caminho em relação a "." por razões de segurança.
O processamento de profundidade pela primeira vez está implícito nessa opção.
Os links simbólicos a seguir são incompatíveis com esta opção.

Em vez disso, eu era capaz de fazer

find . -type d -name 'received_*_output' -exec rm -r {} +

Para o seu caso, parece que citar a glob (asterisco, *) foi a solução, mas eu queria fornecer minha resposta caso alguém mais tivesse o mesmo problema.

NOTA: Anteriormente, minha resposta era fazer o seguinte, mas o @Wildcard apontou as falhas de segurança ao fazê-lo nos comentários.

find . -type d -name 'received_*_output' | xargs rm -r
Pat
fonte
11
Não há uma boa razão para usar xargsaqui. -exec rm -r {} \;ou, melhor, -exec rm -r {} +fará o mesmo sem falhar nos nomes de arquivos de caracteres especiais. Consulte Por que o loop sobre a prática inadequada de saída do find?
Curinga
É bom saber disso. Não vale a pena, IMO, já que o comando ainda faz o trabalho, mas a otimização do desempenho é apreciada.
Pat
11
Se fosse apenas uma otimização de desempenho, eu concordaria com você, mas não é. É uma brecha na segurança. Você não está manipulando arquivos corretamente com espaços em branco nos nomes, e um nome de arquivo criado com códigos maliciosos resultará em perda de dados. Consulte também Implicações de segurança de esquecer de citar uma variável nos shells bash / POSIX ; parte disso é aplicável e, pelo menos, pode lhe dar uma idéia do tipo de problemas de que estou falando.
Curinga
Tente mkdir -p $'blah\nDocuments\n/etc\n/home\n/received__output'no seu diretório e execute o mesmo comando novamente, se você não acredita que há potencial para perda de dados. Ou, já que a pergunta é sobre o Mac OS mkdir -p $'blah\nDocuments\n/Users\n/Applications\n/received__output',. ( Aviso: Você irá apagar todos os seus arquivos se você fizer isso Esse é o meu tipo de ponto..)
Wildcard
0

O que é possível é que não haja nada errado com o comando rm / find, mas que o usuário com o qual você efetuou login não possui permissões de exclusão. Use ls -lpara listar itens com suas permissões e você pode identificar quem você é com os comandos ide groups(deve estar disponível). Se você for o "usuário errado" para fazer isso, será necessário alterar as permissões / propriedade dos arquivos ou alternar para outro usuário.

froztbyte
fonte
0

Experimentar:

shopt -s dotglob           # using Bash
printf '%s\n' ./.Apple*    # test
#rm -rf ./.Apple*    
jan
fonte
11
dotglobé inútil aqui. Veja esta página para um exemplo do que o dotglob faz.
Amphetamachine
-1

Comando simples:

rm `find ./ -name '.Apple*'` -rf

Boa sorte!

KimKha
fonte
4
Isso é extremamente propenso a erros; a localização possui uma chave -exec.
Anton Barkovsky