Exclui subpastas com arquivos específicos em rm -rf / folder / * recursivo

4

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

Não consegui encontrar nenhum até agora.

Agradecemos antecipadamente por sua ajuda!

    
por mr.nothing 13.06.2013 / 13:47

3 respostas

7

Você poderia simplesmente usar find como este

find some_folder ! -name dontshoot.txt -delete

Isso excluirá todos os arquivos e pastas recursivamente, exceto os arquivos dontshoot.txt . 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 contêm dontshoot.txt , mas não serão excluídas, pois não serão esvaziadas quando 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 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 comando find externo atravessa recursivamente some_folder localizando todos os diretórios ( -type d ) e executando ( -exec ) o comando shell fornecido enquanto substitui {} pelo caminho relativo para o diretório encontrado.

O comando find dentro do shell pesquisa os diretórios encontrados em dontshoot.txt . Se não encontrar nada, não haverá saída passada para grep -q '' , que 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 suma, ele percorre todos os diretórios e exclui aqueles que não contêm dontshoot.txt em algum lugar dentro deles.

    
por 13.06.2013 / 14:00
3

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

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 em vez de rm antes de executar.

    
por 13.06.2013 / 13:52
1

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)
}

Ligar como

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

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

    
por 13.06.2013 / 13:58

Tags