como excluir todos os arquivos com extensão específica em pastas nomeadas específicas na grande árvore?

6

Eu tenho uma árvore grande, com muitos arquivos pdf nela. Desejo excluir os arquivos pdf desta árvore, mas somente os arquivos pdf nas subpastas denominados rules/ . Há outros tipos de arquivos dentro de rules/ . As subpastas rules/ não têm outras subpastas.

Por exemplo, eu tenho essa árvore. Tudo abaixo de 'source'

  source/
         A/
            rules/*.pdf, *.txt, *.c,etc..
            etc/
         B/
            keep_this.pdf                
            rules/*.pdf
            whatever/
         C/ 
            D/
               rules/*.pdf
               something/

e assim por diante. Existem pdf arquivos em todo o lugar, mas eu só quero excluir todos os arquivos pdf que estão em pastas chamadas rules/ e nenhum outro lugar.

Eu acho que preciso usar

  cd source
  find  / -type d -name "rules"  -print0 | xargs -0 <<<rm *.pdf?? now what?>>>

Mas não tenho certeza do que fazer depois de obter a lista de todas as subpastas chamadas rules/

Qualquer ajuda é apreciada.

No Linux mint.

    
por Nasser 16.03.2016 / 00:09

4 respostas

8

Eu executaria um find dentro de outro find . Por exemplo, eu executaria esta linha de comando para listar os arquivos que seriam removidos:

$ find /path/to/source -type d -name 'rules' -exec find '{}' -mindepth 1 -maxdepth 1 -type f -iname '*.pdf' -print ';'

Depois de verificar a lista, eu executaria:

$ find /path/to/source -type d -name 'rules' -exec find '{}' -mindepth 1 -maxdepth 1 -type f -iname '*.pdf' -print -delete ';'
    
por 16.03.2016 / 01:03
5

Com um shell que suporta globs estendidos e globs nulos, p. zsh :

for d in ./**/rules/
do
set -- ${d}*.pdf(N)                               
(( $# > 0 )) && printf %s\n $@
done

ou bash :

shopt -s globstar
shopt -s nullglob
for d in ./**/rules/
do
set -- "${d}"*.pdf
(( $# > 0 )) && printf %s\n "$@"
done

substitua printf %s\n por rm se estiver satisfeito com o resultado.

Como você está no gnu / linux, você também pode executar:

find . -type f -regextype posix-basic -regex '.*/rules/[^/]*.pdf' -delete

remova -delete se você quiser executar uma execução a seco.

    
por 16.03.2016 / 02:48
1

Mais fácil seria

find source -name '*.pdf' -path '*/rules/*.pdf' -exec rm '{}' +

Por que o primeiro -name ? Porque vai ser um pouco mais rápido assim. Também + em vez de ; executa um rm com muitos argumentos em vez de muitos com um argumento. Então, menos processos de desova. No bash você pode sair sem citar {} .

    
por 16.03.2016 / 17:38
-1

Você pode usar um script bash para fazer isso (não da melhor maneira):

#!/bin/bash

# Don't screw us up with spaces!
IFS=$'\n'; set -f

DIRS=$(find . -type d -name "rules")

for i in $DIRS; do
  set +f
  rm $i/*.pdf
done
set +f

Isso percorre os diretórios que você encontra no comando find e remove os PDFs de cada diretório.

A linha IFS=$'\n' é para lidar com espaços em nomes de arquivos, e set -f é para lidar com caracteres curinga. Claro, isso está assumindo que você não tem novas linhas em nenhum dos seus nomes de arquivos. Se você fizer isso, a solução se tornará muito mais complicada.

    
por 16.03.2016 / 00:49

Tags