Como renomear arquivos recursivamente em ordem seqüencial?

0

Eu estou ficando louco aqui. Eu tenho muitas pastas como esta

Folder 1/
Subfolder 2/
Item.01 
Item.02
Subfolder 3/
Item.01
Item.02

Eu quero renomear todos os arquivos dentro da pasta 1, de forma recursiva e sequencial, mas seguindo a hierarquia atual, como mostrado por ls e movê-los para uma estrutura simples (todos os arquivos dentro de uma única pasta).

Exemplo:

Folder 1/
Item 01
Item 02
Item 03 (previously Item 01 on Subfolder 2)
Item 04 (previously Item 02 on Subfolder 2)
Item 05 (previously Item 01 on Subfolder 3)

Isso é possível no bash? Muito obrigado!

    
por Freedo 19.03.2018 / 06:44

2 respostas

2

  1. Confira como a opção globstar em bash pode ajudar você:

    shopt -s globstar ; for i in ** ; do echo "$i" ; done
    

    Isso deve fornecer uma lista classificada de todos os itens na árvore de diretórios, mas incluirá entradas (linhas) para arquivos e subdiretórios.

  2. Filtre os subdiretórios:

    shopt -s globstar ; for i in ** ; do [ -f " $i" ] && echo "$i" ; done
    
  3. Introduza um contador e remova os sufixos de arquivos atuais:

    cnt=1
    shopt -s globstar
    for i in ** ; do
      [ -f "$i" ] && echo "${i%%.*}.$cnt"
      cnt=$((cnt=cnt+1))
    done
    
  4. Substitua a instrução echo test pelo mv de sua escolha:

    mv "$i" "${i%%.*}.$cnt"
    
  5. Opcionalmente, desative a opção globstar depois de concluir:

    'shopt +s globstar'
    
por 19.03.2018 / 07:55
1

É mais fácil com zsh :

autoload zmv # best in ~/.zshrc
cd "Folder 1"
n=0; zmv -n '**/Item.<->(#qn^/)' 'Item ${(l:2::0:)$((++n))}'

(remova -n (para dry-run) quando feliz).

  • <-> : qualquer sequência de dígitos decimais ( <x-y> sem limite)
  • (#qn) : para classificação numérica (então Subfolder 10 vem depois Subfolder 2 ).
  • ^/ : exclui arquivos do tipo diretório .
  • ${(l:2::0:)var} : left-pad (e truncar se for maior) $var com 0 s para length 2.

Uma nota de aviso: enquanto o **/ glob se destina a corresponder a qualquer nível de subdiretório, incluindo o nível vazio, para corresponder arquivos no diretório atual, em zmv isso não acontece por causa da passagem dupla faz com o padrão, uma vez para glob e a segunda vez como correspondência de padrão simples para extrair os grupos de captura (e, em seguida, esse segundo **/Item quando o padrão coincide com a falta do / ).

Um trabalho é usar:

zmv -n '(**/)Item.<->(#qn^/)' 'Item ${(l:2::0:)$((++n))}'

ou:

zmv -wn '**/Item.<->(#qn^/)' 'Item ${(l:2::0:)$((++n))}'

mas zmv detecta que é uma correspondência recursiva e ativa a ordem de profundidade (para poder renomear diretórios com segurança). Se você não quiser a ordem de primeira ordem e corresponder arquivos no diretório atual, poderá usar o formato longo de **/ ( (*/)# ):

zmv -n '(*/)#Item.<->(#qn^/)' 'Item ${(l:2::0:)$((++n))}'

Exemplo

Em:

.
├── Subfolder 1
│   ├── Item.01
│   ├── Item.02
│   └── Subsubfolder
│       └── Item.01
├── Subfolder 10
│   ├── Item.01
│   └── Item.02
└── Subfolder 2
    ├── Item.01
    └── Item.02

Dá:

mv -- Subfolder\ 1/Item.01 Item\ 01
mv -- Subfolder\ 1/Item.02 Item\ 02
mv -- Subfolder\ 1/Subsubfolder/Item.01 Item\ 03
mv -- Subfolder\ 2/Item.01 Item\ 04
mv -- Subfolder\ 2/Item.02 Item\ 05
mv -- Subfolder\ 10/Item.01 Item\ 06
mv -- Subfolder\ 10/Item.02 Item\ 07
    
por 19.03.2018 / 08:29