Problema ao usar RENAME para adicionar um prefixo a vários arquivos

Problema ao usar RENAME para adicionar um prefixo a vários arquivos

Encontrei o seguinte problema ao tentar renomear várias centenas de imagens em uma pasta (o que é um dado adquirido, não posso influenciar isso).

Todos os arquivos possuem a estrutura "nome{espaço}sufixo.JPG".
Portanto, as imagens podem ter o mesmonome, mas nesse caso distinguem-se pela suasufixo. Por exemplo

L083192 (1).JPG  
L083192 (2).JPG  
L083192 (3).JPG  
L083192 (4).JPG

ou

L081473 a.JPG  
L081473 b.JPG

O objetivo é adicionar um contador (como prefixo) a todas as imagens com o mesmo nome. Ou seja

1_L083192 (1).JPG  
1_L083192 (2).JPG  
1_L083192 (3).JPG  
1_L083192 (4).JPG

[..]

16_L081473 a.JPG  
16_L081473 b.JPG

O contador é calculado em um loop "FOR /F" que estabelece quais nomes são idênticos, portanto devem receber o mesmo prefixo.
Mas quando tento adicionar o contra-prefixo aplicando o seguinte comando REN:

ren "%%h*" "!cnt!_%%h*"

Eu me deparo com problemas.
( %%h and !cnt! are variables of the "FOR /F" loop)

Esta é a saída correspondente:

L083192 (1).jpg >> 1_L0831921).jpg        [i.e. " (" gone missing]  
[..]  
L083192 (4).jpg >> 1_L0831924).jpg        [id.]

Os dois arquivos "L081473" ainda resultam em umsolteiroarquivo de saída (sem sufixo)!

16_L081473.JPG

Não há dúvida de que existe uma ligação com os mecanismos descritos por dbenham no seuextensa postagem sobre o comando REN (AME), mas não consigo resolver isso no caso acima, pois esperaria que os nomes dos arquivos originais fossem truncados, em vez de alguns caracteres intermediários serem perdidos no processo. Talvez o espaço no nome do arquivo original seja o motivo, embora eu tenha citado esses nomes de arquivo no RENcomando para acomodar espaços? Alguém pode explicar?

Além disso, como RENnão consigo produzir o resultado esperado - ou consegue? -, como posso obter o resultado pretendido usando lote simples?

Também tentei contornar o RENproblema usando COPYou XCOPY, mas os resultados são idênticos. Esses comandos parecem aplicar o mesmo esquema - conforme sugerido cuidadosamente por dbenhamna mesma postagem(veja a nota).


Arquivo em lote

FOR /F %%h IN (input.txt) DO (

    IF NOT "%%h" == "prev" (set /A cnt+=1)  

        [some more logic..]

    cd Images
    ren "%%h*" "!cnt!_%%h*"
    cd..

        [some more logic..]

    set prev=%%h
)

Observação:Eu removi o lote de sua lógica adicional, o que evita que um arquivo seja renomeado mais de uma vez. O "input.txt" contém apenas todas as ocorrências do nome (ou seja, sem sufixo), o que é suficiente para calcular o prefixo. Eu poderia fornecer um arquivo de amostra, mas não encontrei como vinculá-lo a esta mensagem. Além disso, isso não permitiria replicar a renomeação (além disso, a pasta "Imagens" tem aproximadamente 480 Mb).
Os nomes completos dos arquivos nesta pasta são levados em consideração mudando para o subdiretório "Imagens", onde os arquivos aguardam para serem renomeados. ( RENfunciona apenas no diretório atual)

Responder1

Você perdeu ou não percebeu o significado deste parágrafo em minha postagem RENAME:

Qualquer nome pode ser dividido em componentes delimitados por . Caracteres que só podem ser anexados ou excluídos do final de cada componente.Os caracteres não podem ser excluídos ou adicionados ao início ou meio de um componente, preservando o restante com curingas. As substituições são permitidas em qualquer lugar.

Você está tentando adicionar caracteres ao início do nome base, preservando o nome base com curingas. De acordo com minha declaração acima, isso não pode ser feito. Você terá que renomear cada arquivo individualmente. Isto não deve ser particularmente difícil. Presumo que sua outra lógica esteja correta:

FOR /F %%h IN (input.txt) DO (

    IF NOT "%%h" == "prev" (set /A cnt+=1)  

        [some more logic..]

    cd Images
    for %%F in ("%%h*") do ren "%%F" "!cnt!_%%F"
    cd..

        [some more logic..]

    set prev=%%h
)

Observe que o código falhará se %%Fcontiver !devido à ativação atrasada da expansão. Isso pode ser resolvido com um pouco mais de código. Melhor começar com a expansão atrasada desativada e depois ativá-la temporariamente conforme necessário.

setlocal enableDelayedExpansion
for %%N in (!cnt!) do (
  endlocal
  for %%F in ("%%h*") do ren "%%F" "%%N_%%F"
)

informação relacionada