Você pode usar find para isso. Você pode negar os testes em find com -not ou ! . Isso excluirá as correspondências, em vez de encontrá-las.
Você deve ter cuidado para não excluir nenhum dos diretórios pai dos arquivos que deseja manter, especialmente o diretório atual . , portanto, certifique-se de ler a saída completamente antes de excluir.
Com base no seu exemplo, você poderia fazer algo parecido com isso no diretório data .
find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt"
Adicione um ! -path ./path/to/dir para qualquer caminho que você não deseje excluir. Você pode usar metacaracteres como * , mas certifique-se de citar a expressão se fizer isso, por exemplo, "./path*dir" , para evitar expansões indesejadas.
find é recursivo por padrão. Mesmo que não encontremos ./100 aqui, encontraremos todo o seu conteúdo, a menos que eles correspondam ao padrão [ab].txt . Se você não conseguir corresponder todos os nomes que deseja manter, adicione outro teste:
! -path "./100/[ab].txt" ! -path ./100/foo
Isso não encontrará a.txt ou b.txt ou foo , mas todos os outros arquivos serão encontrados.
Quando tiver certeza de ver o que deseja, adicione -delete ao final para excluir os arquivos encontrados:
find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt" -delete