rm -rf todos os arquivos e todos os arquivos ocultos sem. & .. erro

83

rm -rf /some/path/* exclui todos os arquivos não ocultos nesse diretório (e subdireta).

rm -rf /some/path/.* exclui todos os arquivos ocultos nesse diretório (mas não os subdiretórios) e também fornece o seguinte erro / aviso:

rm: cannot remove directory: `/some/dir/.'
rm: cannot remove directory: `/some/dir/..'

Qual é a maneira correta de remover todos os arquivos e pastas ocultos e não ocultos recursivamente em um diretório de destino sem receber o aviso / erro sobre .e ..?

Jake Wilson
fonte

Respostas:

40

Você sempre pode enviar mensagens de erro para /dev/null

rm -rf /some/path/.* 2> /dev/null

Você também pode apenas

rm -rf /some/path/
mkdir /some/path/

... então você não precisará se preocupar com arquivos ocultos.

evilsoup
fonte
2
Mas e se eu quiser excluir apenas os arquivos ocultos?
precisa saber é o seguinte
@CMCDragonkai deve ser uma pergunta diferente, mas você pode encontrar a solução na resposta de Gilles ( rm ..?* .[!.]*deve fazê-lo).
precisa saber é
15
Não excluir e recriar o diretório representa o risco de que as permissões do arquivo não sejam corretas posteriormente (especialmente importantes em ambientes de servidor). Quem poderia criar a pasta com as mesmas permissões de antes automaticamente?
precisa saber é o seguinte
1
@YoLudke Você está absolutamente correto, em muitas situações não importa, mas excluir a pasta e recriar não é semanticamente equivalente a esvaziar essa pasta; tenha cuidado ao fazer isso!
Thomas
A exclusão do diretório nem sempre é possível. No meu caso, o diretório é um volume do docker e, embora eu possa fazer o que quiser dentro do volume, não posso alterar o volume em si dentro do contêiner.
dovidweisz 03/06
85

*corresponde a todos os arquivos que não sejam pontos, .[!.]*corresponde a todos os arquivos de pontos, exceto os .arquivos cujo nome começa com .., e ..?*corresponde a todos os arquivos de pontos, exceto ... Juntos, eles correspondem a todos os arquivos que não sejam .e ... Se algum desses três padrões não corresponder a nada, ele se expande; rm -fnão se importa com argumentos inexistentes, portanto isso não importa.

rm -rf ..?* .[!.]* *

Você também pode usar find. Isso é mais complexo, mas tem a vantagem de funcionar, mesmo que haja tantos arquivos que os curingas acima se expandam além do limite de comprimento da linha de comando do sistema.

find . -name . -o -prune -exec rm -rf -- {} +

Você pode achar mais claro remover e recriar o diretório. Isso tem a vantagem (ou desvantagem, conforme o caso) de resultar em um diretório vazio, mesmo que outro programa esteja criando simultaneamente arquivos no diretório original.

Gilles
fonte
8
Essa deve ser a resposta aceita, pois evita a travessia dos pais e a possível exclusão.
rbellamy
A findalternativa retorna "sucesso" mesmo que algum arquivo não seja excluído com êxito; não é bom para script.
Franklin Yu
Com relação ao seu segundo findcomando, a página de manual dos estados find "Como -delete implica -thth, você não pode usar utilmente -une e -delete juntos." - você ainda usa -prune -delete?
Doktor J
@DoktorJ De fato, -prunenão faz nada aqui. E, ao ler de volta, vejo que não respondi à pergunta corretamente: tomei o cuidado de não recorrer, mas a pergunta pede explicitamente a exclusão recursiva. Eu corrigi minha resposta.
Gilles
2
@haylem No zsh, você precisa escrever em .[^.]*vez de .[!.]*quando a substituição do histórico está ativada (que por padrão é o caso interativamente, mas não nos scripts), porque o zsh analisa !como uma referência do histórico. Mas no zsh você não precisaria disso em primeiro lugar, basta usar *(D)arquivos de ponto (sem .ou ..) na correspondência de curinga.
Gilles
21

Acabei de perceber que esta é a maneira mais conveniente na maioria das distribuições Linux:

ls -A1 | xargs rm -rf

Onde

-A= lista tudo, exceto . e..

-1 = coloca todos os itens em uma linha

godzillante
fonte
4
desvantagem que eu vejo é: você precisa 'cd' no diretório para fazer isso.
kumar
ls -A1 /your/path/ | xargs rm -rfdeve aplicar
godzillante
não ... não ajuda - Por exemplo: ls -A1 ~ / test / | xargs rm -rf Este comando exclui arquivos nos quais eu estou atualmente 'cd into' .. não no diretório ~ / test.
kumar
5
Não funciona se qualquer um dos nomes de arquivo contiver espaços em branco, novas linhas, aspas ou barras invertidas.
Stéphane Chazelas
1
-1 Por causa do comentário acima. ↑↑↑↑↑↑↑↑
somethingSomething
15

Altere a dotglobopção do seu shell e use *, ou use algo parecido find.

find somedir -mindepth 1 -delete
Ignacio Vazquez-Abrams
fonte
2
Ou você pode simplesmente rm -rf /some/dircriar um novo diretório vazio em seu lugar.
Tripleee 26/05
Melhor opção até agora. Muito seguro, pois você especifica explicitamente o caminho do diretório.
Yanick Girouard 11/07
4

Isso deve funcionar como a resposta do @Gilles, mas mais compacto:

rm -rf {,.[!.],..?}*

ou

rm -rf dir/to/files/{,.[!.],..?}*

Também deve adicionar um ifpara uso em scripts apenas para garantir:

if [ -d "$DIR" ]; then
    rm -rf ${DIR}/{,.[!.],..?}*
fi
Paweł Prażak
fonte
1
Curiosamente, como um alias do bash no Ubuntu 16.04 LTS, a resposta anterior não estava funcionando. No entanto, alias cleandir='rm -rf {,.[!.],..?}*'faz.
Steven Ventimiglia
3

Find é seu amigo.

find ! -name '.' ! -name '..' -delete

% find ! -name '.' ! -name '..'
./test
./test4
./test4/.test6
./test3
./.test5
./test2
% find ! -name '.' ! -name '..' -delete    
% find ! -name '.' ! -name '..'     
%             

Se você deseja usar a pesquisa recursiva em outro diretório atual ($ PWD), adicione um caminho logo após o findcomando; por exemplo find /path ! -name '.' ! -name '..' -delete,. Se você deseja apenas descer o nnúmero de diretórios, use a -maxdepth nopção logo após o /pathparâmetro

O comando acima foi testado em um sistema Ubuntu 13.04. Provavelmente funcionará em outros sistemas Linux modernos.

laebshade
fonte
para excluir todos os diretórios no diretório atual que você poderia fazerfind . ! -name '.' ! -name '..' -type d -delete
Andy
2

Qual é a maneira correta de remover todos os arquivos e pastas ocultos e não ocultos recursivamente em um diretório de destino sem receber o aviso / erro sobre. e ..?

Supondo que o diretório em questão seja ./dir,

rm -rf ./dir

removeria todos os arquivos ./dir, incluindo arquivos e diretórios ocultos, recursivamente e incluindo o ./dirpróprio diretório.

Se você não deseja excluir o próprio diretório, poderá recriá-lo posteriormente ou usar

find ./dir -mindepth 1 -delete

ou se você findnão suportar -delete,

find ./dir -mindepth 1 -depth -exec rm -rf {} ';'

Usar -mindepth 1permite manter o diretório de nível superior ./dir.

Kusalananda
fonte
isso deve ser marcado como a melhor resposta
kitingChris 30/07
1

Eu sugiro que você experimente

Turn ON pontos (arquivos ocultos)

  • conjunto dotglob

    shopt -s dotglob

Turn OFF pontos

  • incerto dotglob

    shopt -u dotglob

Esse método funcionou exatamente como eu desejava para um comando de cópia que estava ausente nos diretórios ocultos.

    shopt -s    dotglob
    cp    -rvn  ./$from/*  ./$too/
    shopt -u    dotglob

Então eu fiz uma remoção (exclusão) e oops ...

    shopt -s    dotglob
    rm -fr ../message_splitter--044a/*
    shopt -u    dotglob

... isso funciona também!

Ocorre-me que você, caro leitor, não pode ver o message_splitterdiretório. De qualquer maneira, ele possui uma .svnpasta que precisa ser removida e copiada para o.

Da manpágina ...

dotglob Se definido, o bash inclui nomes de arquivos que começam com um `. ' nos resultados da expansão do nome do caminho.

referências:

vai
fonte
-2

Tente este código:

Dirlist=``find /some/path/ -type d -name '.[^.]*'`
for HiddenDir in $Dirlist
do
    rm -rf $HiddenDir
done
siz
fonte