Excluindo certos arquivos e diretórios ao excluir arquivos

9

Meu diretório de nível superior é data . data inclui vários diretórios e esses diretórios possuem subdiretórios. Eu preciso remover todos os arquivos e diretórios dentro de data/ , exceto vários arquivos em alguns diretórios.

Por exemplo, os dados incluem os diretórios 100 e 101 . Eu só quero manter a.txt e b.txt arquivos em 100/ e c.txt e d.txt arquivos em 101/ ao remover todos os outros arquivos e diretórios em 100 e 101 .

Exemplo:

.
├── 100
│   ├── a.txt
│   ├── b.txt
│   ├── c.txt
│   └── d.txt
└── 101
    ├── a.txt
    ├── b.txt
    ├── c.txt
    └── d.txt

Eu uso o comando rm -rf !(a.txt|b.txt) , mas não posso aplicar esse comando para cada diretório automaticamente.

    
por deepblue 02.01.2018 / 13:47

2 respostas

10

Como você já descobriu, você pode usar o recurso extglob que está ativado com:

shopt -s extglob

Isso permite excluir correspondências para que você possa fazer coisas como:

rm 100/!([ab].txt) 101/!([cd].txt)

É uma boa ideia testá-lo com echo primeiro. Este exemplo corresponderá a qualquer item dentro de 100/ , que não é a.txt ou b.txt e nada dentro de 101/ , que não é c.txt ou d.txt . Se as mesmas regras para 100/ se aplicarem a 102/ , você poderá fazer, por exemplo:

10[02]/!([ab].txt) # or
{100,102}/!([ab].txt)
    
por dessert 02.01.2018 / 14:02
6

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
    
por Zanna 02.01.2018 / 14:13