Renomeando arquivos adicionando o sufixo “ciclando”

5

Eu tenho um diretório contendo subdiretórios contendo muitos arquivos nomeados como:

file1.tif
file2.tif
file3.tif
file4.tif
file5.tif
file6.tif
file7.tif...

Eu quero adicionar um sufixo "cycle" c1 , c2 e c3 , para obter os nomes dos arquivos:

file1c1.tif
file2c2.tif
file3c3.tif
file4c1.tif
file5c2.tif
file6c3.tif
file7c1.tif...

E isso em todos os subdiretórios do diretório principal.

Mas não consigo descobrir como fazer isso.

Isso é possível? Como?

    
por Philippe P 30.08.2016 / 12:01

3 respostas

7

Com find + o perl% prename (também conhecido como rename em algum Ubuntus anterior) você poderia combinar a sequência de dígitos antes de um literal . e então escrevê-lo no formato desejado usando a divisão do módulo eg

find . -name '*.tif' -execdir prename -vn -- 's/(\d+)\./sprintf "%dc%d.", , (-1)%3+1/e' {} +

(as sinalizações -vn permitem que você execute um 'dry run' para ver como os arquivos seriam renomeados antes de confirmar).

dado

$ tree
.
├── bar
│   ├── file1.tif
│   ├── file2.tif
│   ├── file3.tif
│   ├── file4.tif
│   ├── file5.tif
│   ├── file6.tif
│   └── file7.tif
├── foo
│   ├── egg
│   │   ├── file1.tif
│   │   └── file2.tif
│   ├── file1.tif
│   ├── file2.tif
│   └── file3.tif
└── spam
    ├── file1.tif
    └── file2.tif

4 directories, 14 files

Então

find . -name '*.tif' -execdir prename -- 's/(\d+)\./sprintf "%dc%d.", , (-1)%3+1/e' {} +

resulta em

$ tree
.
├── bar
│   ├── file1c1.tif
│   ├── file2c2.tif
│   ├── file3c3.tif
│   ├── file4c1.tif
│   ├── file5c2.tif
│   ├── file6c3.tif
│   └── file7c1.tif
├── foo
│   ├── egg
│   │   ├── file1c1.tif
│   │   └── file2c2.tif
│   ├── file1c1.tif
│   ├── file2c2.tif
│   └── file3c3.tif
└── spam
    ├── file1c1.tif
    └── file2c2.tif

4 directories, 14 files
    
por steeldriver 30.08.2016 / 15:15
6

Edite com base no comentário:

Se você quiser percorrer o contador, ou seja, <number> em c<number> para alternar entre 1 a 3:

Secagem:

shopt -s globstar
for d in **/*/; do 
    ( cd "$d" && pwd && count=1 && shopt -s nullglob && for f in file*.tif; do 
        echo mv -i "$f" "${f%.tif}"c${count}.tif
        if ((count=3)); then 
            count=1
        else
            ((count++))
        fi
     done ) 
done

Ação:

shopt -s globstar
for d in **/*/; do 
    ( cd "$d" && count=1 && shopt -s nullglob && for f in file*.tif; do 
        mv -i "$f" "${f%.tif}"c${count}.tif
        if ((count=3)); then 
            count=1
        else
            ((count++))
        fi
     done ) 
done

Exemplo:

$ tree
.
├── bar
│   ├── file1.tif
│   ├── file2.tif
│   ├── file3.tif
│   └── file4.tif
├── foo
│   ├── egg
│   │   ├── file1.tif
│   │   └── file2.tif
│   ├── file1.tif
│   ├── file2.tif
│   └── file3.tif
└── spam
    ├── file1.tif
    └── file2.tif

$ shopt -s globstar
$ for d in **/*/; do ( cd "$d" && pwd && count=1 && shopt -s nullglob && for f in file*.tif; do \
    echo mv -i "$f" "${f%.tif}"c${count}.tif; if ((count=3)); then count=1; else ((count++)); fi; done ); done
/home/foobar/bar
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif
mv -i file3.tif file3c3.tif
mv -i file4.tif file4c1.tif
/home/foobar/foo
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif
mv -i file3.tif file3c3.tif
/home/foobar/foo/egg
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif
/home/foobar/spam
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif

$ for d in **/*/; do ( cd "$d" && count=1 && shopt -s nullglob && for f in file*.tif; do \
    mv -i "$f" "${f%.tif}"c${count}.tif; if ((count=3)); then count=1; else ((count++)); fi; done ); done

$ tree
.
├── bar
│   ├── file1c1.tif
│   ├── file2c2.tif
│   ├── file3c3.tif
│   └── file4c1.tif
├── foo
│   ├── egg
│   │   ├── file1c1.tif
│   │   └── file2c2.tif
│   ├── file1c1.tif
│   ├── file2c2.tif
│   └── file3c3.tif
└── spam
    ├── file1c1.tif
    └── file2c2.tif

Resposta original:

com bash :

shopt -s globstar
for d in **/*/; do ( cd "$d" && pwd && count=1 && shopt -s nullglob \
    && for f in file*.tif; do echo mv -i "$f" "${f%.tif}"c${count}.tif; \
        ((count++)); done ); done
  • Aqui estamos dando um loop sobre os nomes dos diretórios, a opção globstar shell nos permite atravessar o diretório recursivamente

  • A parte dentro de () é executada em um subshell, isso é para evitar que o cd seja modificado no shell atual

  • Estamos cd -ing nos diretórios, localizando os arquivos file*.tif e renomeando-os conforme necessário

  • mantendo um contador de incremento, count , para cada arquivo enquanto renomeia

O exemplo acima é de execução a seco e mostrará o diretório onde a renomeação será feita e qual comando mv será executado. Se satisfeito, faça:

shopt -s globstar
for d in **/*/; do ( cd "$d" && count=1 && shopt -s nullglob && \
  for f in file*.tif; do mv -i "$f" "${f%.tif}"c${count}.tif; ((count++)); done ); done

Existe uma ressalva de que, como o shell faz a ordenação lexical, arquivos, por exemplo, file10.tif será renomeado antes de file2.tif . Se você não quiser isso, faça alguma classificação antes de renomear ou usar a opção zsh with numericglobsort .

    
por heemayl 30.08.2016 / 12:29
0

Graças a heemayl, tudo foi resolvido. Tivemos que modificar o loop de incremento de ciclo indicado um pouco, já que ele não funcionava em nossas mãos. Nós mudamos: if ((contagem = 3)) para dentro: if (("$ count" == 3)) O código final que estamos usando agora é:

    shopt -s globstar
for d in **/*/; do 
    ( cd "$d" && count=1 && shopt -s nullglob && for f in *.tif; do 
       echo mv -i "$f" "${f%.tif}"c${count}.tif

if (("$count"==3)); then 
count=1
        else 
((count++))
        fi
     done ) 
done

Obrigado novamente ao heemayl por sua ajuda e paciência ...

    
por Philippe P 01.09.2016 / 11:57