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.