Encontre e apague arquivos, mantendo todos os arquivos correspondentes em um diretório específico [duplicado]

0

Eu tenho uma pergunta interessante, que pode ou não ser fácil :( Eu tenho tentado descobrir uma maneira de integrar as opções do comando 'find' no linux.

Basicamente, eu tenho uma árvore de diretórios, dentro da qual pode haver vários exemplos dos arquivos que precisam ser mantidos ou excluídos. Todos os arquivos compartilham as mesmas extensões, por causa do argumento .XX (embora a ideia seja ser o mais genérica possível para que possa ser qualquer arquivo). Eu quero excluir todos os arquivos .XX dentro da árvore de diretórios, EXCETO onde os arquivos estão dentro de uma pasta específica (sempre será o mesmo título, no exemplo chamado YYY).

Digamos que eu tenha que seguir a estrutura (onde cada subdiretório pode conter muitos arquivos que eu não quero tocar ou afetar ao lado daqueles que eu faço):

folder_root:
|
|--> Subdir_1/interesting_file_1.XX
|--> Subdir_1/interesting_file_2.XX
|--> Subdir_1/unrelated_interesting_file_1.AA
|--> Subdir_2
|--> Subdir_3/interesting_file_3.XX
|--> YYY/interesting_file_4.XX
|--> YYY//interesting_file_5.XX

Eu quero ficar com:

folder_root:
|
|--> Subdir_1/unrelated_interesting_file_1.AA
|--> YYY/interesting_file_4.XX
|--> YYY/interesting_file_5.XX

A nota é que o diretório YYY pode estar em qualquer lugar, e pode haver muitos deles, então não é possível ter uma lista de caminhos de diretório que precisam ser excluídos para construir uma grande lista de exclusão.

Primeiro, fiz um Find básico como tal: find . -iname "*.XX" . Então eu olhei para adicionar o -printf "%h\n" para a saída dos diretórios que contêm os arquivos .XX. O que estou me esforçando para fazer é pegar essa lista de saída e usá-la para informar o processo de exclusão ou, conforme o caso, não excluir. Eu suponho que eu poderia usar grep para remover quaisquer pastas YYY da saída para um arquivo temporário, usar um while read loop, então pushd e popd para mover e depois para fora das pastas, usando um simples find . -iname "*.XX" -delete dentro de cada subdiretório (depois, usando a opção -empty em find para limpar todos os diretórios vazios deixados como resultado). Isso, no entanto, parece muito contundente, com uma grande marreta, que pode ser muito intensiva no sistema, especialmente quando lidamos com potencialmente centenas de subdiretórios.

Estou interessado se houver uma maneira 'melhor', que seja mais simples, geralmente menos intensiva e confiável (especialmente se você acabar tendo que executá-la três ou quatro vezes para três ou quatro tipos diferentes de arquivos)?

Pode não haver, mas vale a pena uma pergunta rápida :) Por que usar uma marreta quando um simples martelo faria !? :)

Nota final, eu não posso adicionar comandos shell adicionais ao sistema (e os sistemas usados são uma mistura de Ubuntu e Centos), então, quando possível, ele precisaria usar o conjunto de comandos preexistente (suponha que nenhum outro módulo seja instalado, exceto Tree, que eu sei sobre). Espero que a pergunta seja clara e "genérica" o suficiente para ser útil para os outros em diferentes situações, se uma resposta simples for encontrada.

    
por Owen Morgan 09.03.2018 / 20:01

2 respostas

0

Eu não acho que você precise de pushd popd etc. porque find produz nomes de caminhos completos.

Qualquer abordagem readline terá resultados interessantes se um nome de arquivo contiver um retorno de carro seguido por um asterisco.

A solução geral é gerar uma lista terminada em null de todos os candidatos com find, winnow with grep, executar com xargs:

find . -iname "*.XX" -print0 | grep -vzf keep_these.txt | xargs -0 echo rm -- # remove the echo to ACTUALLY delete files

"keep_these.txt" é uma lista de diretórios a serem excluídos, um por linha, incluindo barras iniciais e finais, como:

/YYY/ 
/I love this directory/

Se você não precisa da regex para identificar seus diretórios (apenas strings fixas), adicione -F ao grep.

    
por 09.03.2018 / 20:13
0

Isso deve funcionar:

find folder_root/ -name Subdir_2 -prune -o -name Subdir_3 -prune -a -type f

Se isso encontrar o conjunto correto de arquivos, você poderá adicionar -delete ao final do comando find .

    
por 09.03.2018 / 20:11

Tags