Remover recursivamente arquivos


140

Alguém tem uma solução para remover os irritantes arquivos ._ e .DS_Store obtidos após mover arquivos de um Mac para um servidor Linux?

especificar um diretório inicial e deixá-lo ir? como / var / www / html / down ...


Embora não seja um IMO duplicado, você deve dar uma olhada no seguinte: stackoverflow.com/questions/1280429/…
Grundlefleck

Embora não seja o que você está perguntando. Eu diria que esta é uma solução melhor: unix.stackexchange.com/questions/9665/…
Viktor

Respostas:


169

mude para o diretório e use:

find . -name ".DS_Store" -print0 | xargs -0 rm -rf
find . -name "._*" -print0 | xargs -0 rm -rf

Não testado, experimente-os sem o xargs primeiro!

Você pode substituir o período após a localização, pelo diretório, em vez de mudar para o diretório primeiro.

find /dir/here ...

2
Sei que a pergunta dele não pediu, mas nunca me lembro: seu exemplo lida com nomes de arquivos com espaços?
Grundlefleck

4
Sim, é para isso que servem print0 e -0 a xargs. Normalmente, ele não manipula os espaços corretamente, no entanto, com print0, ele imprime o nome do arquivo com um caractere nulo no final da linha, que o xarg com -0 utilizará para passar o caminho completo para xargs sem a chance de ter o espaço em branco. sendo usado um segundo ou terceiro parâmetro para o comando rm, o que pode ser muito ruim!
X-Istence

7
@X: o findutils mais recente suporta uma -deleteação que pode encurtar isso. @JT: Isso pesquisa recursivamente em .. Depende de quantos arquivos e subdiretórios existem ... você não pode simplesmente proibir os uploads?
ephemient

1
Usando a -rbandeira (recursivo) não é recomendado neste caso, desde que você não deseja excluir qualquer diretório ..
Daniel Zohar

2
@IlmariKaronen: bom ponto. Não command rmseria uma solução melhor (ou seja, mais direta)? (Por "direto", quero dizer que lida especificamente com o problema em questão e nada mais, e, portanto, é menos provável que tenha efeitos colaterais indesejados e também será mais auto-explicativo para quem precisar manter o código
iconoclast

93
find /var/www/html \( -name '.DS_Store' -or -name '._*' \) -delete

86

Os novos findutils suportam -delete, então:

find . -name ".DS_Store" -delete

Adicionar -printpara também obter uma lista de exclusões.

O comando funcionará para você se você tiver um sistema POSIX atualizado, acredito. Pelo menos, funciona para mim no OS X 10.8 e funciona para outras pessoas que o testaram no macOS 10.12 (Mojave).

Os nossos agradecimentos a @ephemient em um comentário na postagem de @ X-Istence (consideramos útil o suficiente para justificar sua própria resposta).


1
Também funciona no OSX 10.6.
Hr 12/12

3
Solução mais limpa e simples, +1!
limist

6
@OneOfOne: como diz o meu comentário, consegui isso no @ ephemient. Como iniciante, achei sua solução (talvez mais correta) muito menos legível e utilizável. Eles podem ser funcionalmente idênticos, mas acho que essa sintaxe fornece mais clareza.
rattray

1
O '.' não é necessário porque findrecursa no diretório de trabalho atual por padrão.
Tom Russell

Nas versões mais recentes do programa, o diretório pode ser omitido e implicará no diretório de trabalho atual ( wikipedia ). Você ainda precisa .do macOS 10.12 (Sierra).
Dem Pilafian

18

Comando simples:

rm `find ./ -name '.DS_Store'` -rf
rm `find ./ -name '._'` -rf

Boa sorte!


1
Isso funciona muito bem. Mas uma palavra de cautela, eu apenas usei esse rm -i achado ./ -name '* py'` -rf , which did NOT prompt me to delete files. you will need to take it on the end (i.e. -rfi`). Graças a Deus pelo meu script de backup.
Ryanjdillon

1
Se houver muitos arquivos, isso interrompe o erro:-bash: /bin/rm: Argument list too long
Viktor

12
cd /var/www/html && find . -name '.DS_Store' -print0 | xargs -0 rm
cd /var/www/html && find . -name '._*' -print0 | xargs -0 rm

2
Eu gostei mais deste simplesmente porque o "rm" não tem "-r", o que não é necessário para esta tarefa específica.
lotsoffreetime

6

Você pode mudar para zsh em vez de bash. Isso permite usar ** para corresponder arquivos em qualquer lugar da árvore de diretórios:

$ rm /var/www/html/**/_* /var/www/html/**/.DS_Store

Você também pode combiná-los assim:

$ rm /var/www/html/**/(_*|.DS_Store)

O Zsh tem muitos outros recursos que faltam para o bash, mas só esse vale a pena fazer a troca. Está disponível na maioria das distribuições (provavelmente todas) do Linux, assim como no cygwin e no OS X.

Você pode encontrar mais informações no site zsh .


1
Um possível problema: como você não usa xargs, você pode encontrar a restrição de comprimento do argumento da linha de comando. Além disso, Bash 4 suportes **também :-) (embora não por padrão, shopt -s globstarprecisa ser definido)
ephemient

4
find . -name "FILE-TO-FIND"-exec rm -rf {} \;

O uso de exec para cada arquivo encontrado não é rápido. É mais rápido encontrar os impressos e, em seguida, usar xargs para chamar o rm uma vez.
X-Istence

3
No entanto, se você tiver um findque o suporte, +é semelhante ao xargs: find . -name "FILE-TO-FIND" -exec rm -rf {} +- (também, você está perdendo um espaço antes -exec)
Pausado até novo aviso.

3
nós nunca tivemos xargs no meu dia. E nós tivemos que caminhar até a escola, subida ambas as maneiras .......
Martin Beckett

3

Exemplo para excluir "Thumbs.db" recursivamente;

find . -iname "Thumbs.db" -print0 | xargs -0 rm -rf

Validar por:

find . -iname "Thumbs.db"

Agora, isso não deve exibir nenhuma das entradas com "Thumbs.db", dentro do caminho atual.


Certifique-se de que sua resposta imprima uma lista do que está sendo excluído e explique por que alguém pode querer usar xargse em print0vez de exec(existem motivos).
Josh Habdas 21/03/19

3

É melhor ver o que está removendo adicionando -print a esta resposta

find /var/www/html \( -name '.DS_Store' -or -name '._*' \) -delete -print

2

se você tiver o Bash 4.0 ++

#!/bin/bash
shopt -s globstar
for file in /var/www/html/**/.DS_Store /var/www/html/**/._ 
do
 echo rm "$file"
done

2
A execução de uma nova cópia do rm para cada arquivo é um desperdício.
X-Istence

2
@ X-istência otimização prematura é um desperdício
Lucina

Promovido por originalidade e uso de inovações mais recentes do bash.
Josh Habdas 21/03/19

1

Algumas coisas a serem observadas:

'-delete' não é recursivo. Portanto, se .TemporaryItems (folder) tiver arquivos, o comando falhará.

Existem muitos desses arquivos irritantes criados por macs: .DS_Store ._. DS_Store .TemporaryItems .apdisk

Este comando aborda todos eles. Evita a execução de encontrar repetidas vezes para várias correspondências.

find /home/foo \( -name '.DS_Store' -or -name '._.DS_Store' -or -name '._*' -or -name '.TemporaryItems' -or -name '.apdisk' \) -exec rm -rf {} \;

0

Isso também funciona:

sudo rm -rf 2018-03-*

aqui seus arquivos são excluídos com nomes do formato 2018-03- (outra coisa)

mantenha simples


Você não explica quando alguém pode prefixar um comando sudonem fornece informações sobre como rmfunciona no contexto da sua resposta.
Josh Habdas 21/03/19
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.