Questão Excluir subpastas com arquivos específicos em rm -rf / folder / * recursivo


Gostaria de saber se é possível especificar alguma condição elegante (parâmetro talvez?) Em rm -rf /folder/* não para excluir suas subpastas, que contêm arquivos com o nome "dontshoot.txt".

Eu não consegui encontrar nenhum até agora.

Agradeço antecipadamente por sua ajuda!


4


origem


no meu conhecimento rm não pode excluir padrões, você terá que escrever uma função ou script para fazer isso. - Cobra_Fast


Respostas:


Você poderia simplesmente usar find como isso

find some_folder ! -name dontshoot.txt -delete

Isso excluirá todos os arquivos e pastas de forma recursiva, exceto dontshoot.txt arquivos. Como observado nos outros comentários, é sempre útil testá-lo sem excluir, o que pode ser feito simplesmente assim.

find some_folder ! -name dontshoot.txt 

No entanto, isso listará todas as pastas, mesmo aquelas que contenham dontshoot.txt mas eles não serão excluídos, já que não estarão vazios ao usar -delete.

Editar:

Concordo que a interpretação fedorqui da questão é mais razoável do que a minha. Para excluir apenas pastas que não contêm dontshoot.txt em algum lugar profundo dentro de sua estrutura de árvore uma solução ineficiente terrível seria

find some_folder -type d -exec \
   sh -c "find {} -name dontshoot.txt | grep -q '' || echo rm -fr {}" \;

Explicação:

O exterior find comando percorre recursivamente através some_folder encontrar todos os diretórios (-type d) e executar (-exec) o comando shell fornecido ao substituir {} pelo caminho relativo para o diretório encontrado.

o find comando dentro do shell procura os diretórios encontrados para dontshoot.txt. Se não encontrar nada, não haverá saída passada para grep -q ''  que, portanto, retornará False e a última parte será executada, o que removerá o diretório completo (que certamente não contém dontshoot.txt) recursivamente.

Em resumo, ele percorre todos os diretórios e exclui aqueles que não contêm dontshoot.txt em algum lugar dentro deles.


7



Tenho uma duvida: e se tivermos uma pasta t / com dontshoot.txt e otherfile.txt? Eu acho que seu código excluiria o otherfile.txt, embora eu acho que não deve basear-se no OP. - fedorqui
Sim, você está certo, eu estendi a resposta para sua interpretação mais razoável da questão. - buergi
Parabéns, esta é uma ótima resposta! - fedorqui


Não é possível excluí-los dentro rm comando.

Você pode fazer algo assim:

for dir in /folder/*
do
  echo $dir
  if [ ! -f "$dir/dontshoot.txt" ]; then
    rm -rf "$dir"
   fi
done

Importante:

Verifique com ls ao invés de rm antes de executar.


3



Fui votado e derrotado ao mesmo tempo! - fedorqui
Não sou eu, juro! ; D Obrigado pela resposta, vou verificar. - mr.nothing
@ mr.nothing, sempre tente o seu comando com ls antes de usá-lo com rm! - fedorqui
@ fedorqui Provavelmente a melhor solução. Eu tentei inventar algo find, mas eu não acho que essa condição pode ser feita com isso. - glglgl
O problema com esta solução é que ela não funcionará recursivamente. No entanto, a questão não deixa claro se isso é desejado ou não. - buergi


A seguinte função pode funcionar, mas não tive tempo para testá-la.

// $1 = directory to remove
// $2 = exclude pattern
function rmx()
{
    rm -f $(find $1 * | grep -v $2)
}

Ligue como

rmx get/rid/of/this/ ".*?not-these-files.*?"

Talvez isso possa pelo menos servir como uma ideia de como abordar esse problema ...


1



findé o caminho certo, mas desta forma é complicado, é muito mais fácil excluir os arquivos na pesquisa imediatamente e usar o find -delete bandeira. Confira meu anwer para um exemplo completo. - buergi