Arquivos faltando após usar mv e substituição de parâmetro em um loop

1

Perguntas relacionadas a arquivos ausentes após mv não parecem responder à minha pergunta. Os seguintes comandos foram executados dentro do diretório de trabalho onde os arquivos estão localizados, resultando em arquivos ausentes.

Etapa 1

Eu tenho uma matriz ordenada de nomes de arquivos $layers criados com layers=$(ls cropped* | sort -nk1.9) :

IFS=$'\n';for file in $layers; do echo $file; done  
cropped_1.png  
cropped_2-a.png  
cropped_2-b.png    
cropped_2.png  
cropped_3-a.png  
cropped_3-b.png  
cropped_3.png  
cropped_4-a.png  
cropped_4-b.png  
cropped_4-c.png  
cropped_4-d.png  
cropped_4-e.png  
cropped_4-f.png  
cropped_4-g.png  
cropped_4.png  
cropped_5-a.png  
cropped_5-b.png  
cropped_5.png  
--More--

Etapa 2

Eu executei o seguinte loop para substituir tudo seguindo o _ em cada nome de arquivo:

i=1;IFS=$'\n';for file in $layers; do echo ${file/#*_*/cropped_$((i++)).png}; done  
cropped_1.png
cropped_2.png
cropped_3.png
cropped_4.png
cropped_5.png
cropped_6.png
cropped_7.png
cropped_8.png
cropped_9.png
cropped_10.png
cropped_11.png
cropped_12.png
cropped_13.png
cropped_14.png
cropped_15.png
cropped_16.png
cropped_17.png
--More--

Passo 3 - Perigo, Robinson!

Isso parecia bom até agora. Por isso, tentei renomear cada arquivo com mv usando o loop a seguir, que eu esperava que resultasse em algo como mv cropped_2-a.png cropped_2.png , depois mv cropped_2-b.png cropped_3.png e assim por diante:

i=1;IFS=$'\n';for file in $layers; do mv $file ${file/#*_*/cropped_$((i++)).png}; done

Isso deu um único erro para o primeiro arquivo.

mv: ‘cropped_1.png’ and ‘cropped_1.png’ are the same file

Eu assumi que isso daria esse erro para cada nome de arquivo em que mv SOURCE DEST correspondesse. Em vez disso, apenas deu o erro no primeiro arquivo no loop.

A parte estranha é que vários arquivos estão faltando. Os únicos arquivos restantes são os seguintes:

ls cropped* | sort -nk1.9
cropped_1.png
cropped_141.png
cropped_142.png
cropped_143.png
cropped_144.png
cropped_145.png
cropped_146.png
cropped_147.png
cropped_148.png
cropped_149.png
cropped_150.png
cropped_151.png
cropped_152.png
cropped_153.png
cropped_154.png
cropped_155.png

Pergunta

Para onde os arquivos ausentes foram movidos?

Foram 140 arquivos antes de criar algumas duplicatas com nomes como cropped_2-a.png , resultando em 155 arquivos no total. Se os arquivos 141-155 foram movidos com sucesso, onde estão os arquivos 2-140? Por que eles não se movem para o destino esperado? o diretório de trabalho atual?

Notas

Se eu não adicionar arquivos com nomes como cropped_2-a.png , o loop exibirá a mensagem de erro para cada arquivo e os arquivos permanecerão inalterados:

i=1;IFS=$'\n';for file in $layers; do mv $file ${file/#*_*/cropped_$((i++)).png}; done
mv: ‘cropped_1.png’ and ‘cropped_1.png’ are the same file
mv: ‘cropped_2.png’ and ‘cropped_2.png’ are the same file
mv: ‘cropped_3.png’ and ‘cropped_3.png’ are the same file
mv: ‘cropped_4.png’ and ‘cropped_4.png’ are the same file
mv: ‘cropped_5.png’ and ‘cropped_5.png’ are the same file
--More--

Eu testei com nomes de arquivos como cropped_2a.png (no - ) e duplique o problema de arquivos ausentes.

Quando eu tento com mv -v para ver o que está acontecendo, parece estar renomeando os arquivos como esperado, mas quando eu verifico, os arquivos estão faltando. Embrulhar a substituição de parâmetro 1 ${file/#*_*/cropped_$((i++)).png} entre aspas duplas não resolve isso.

i=1;IFS=$'\n';for file in $layers; do mv -v $file "${file/#*_*/cropped_$((i++)).png}"; done
‘cropped_2-a.png’ -> ‘cropped_2.png’
‘cropped_2-b.png’ -> ‘cropped_3.png’
‘cropped_2.png’ -> ‘cropped_4.png’
‘cropped_3-a.png’ -> ‘cropped_5.png’
‘cropped_3-b.png’ -> ‘cropped_6.png’
‘cropped_3.png’ -> ‘cropped_7.png’
‘cropped_4.png’ -> ‘cropped_8.png’
‘cropped_5.png’ -> ‘cropped_9.png’
‘cropped_6.png’ -> ‘cropped_10.png’
--More--

Testando um comando mv mais simples usando a substituição de parâmetros conforme o argumento de definição funciona:

testy="cropped_2-b.png"
mv -iv $testy ${testy/#*_*/cropped_999.png}

Isso também funciona:

i=998
testy="cropped_2-b.png"
mv -iv $testy ${testy/#*_*/cropped_$((i++)).png}

‘cropped_2-b.png’ -> ‘cropped_998.png’

testy="cropped_3-a.png"
mv -iv $testy ${testy/#*_*/cropped_$((i++)).png}

‘cropped_3-a.png’ -> ‘cropped_999.png’

Eu não consegui determinar por que ele falha durante o loop for depois que o mesmo erro de arquivo é exibido ou para onde os arquivos realmente vão.

    
por iyrin 01.03.2015 / 21:53

1 resposta

2

cropped_2-a.png foi renomeado para cropped_2.png . Isso substituiu o original cropped_2.png . Então 2 linhas depois este arquivo foi renomeado para cropped_4.png .

A melhor maneira de evitar esse problema é mover os arquivos para um diretório diferente, inicialmente vazio, ao renumerá-los, para que você não precise se preocupar com a incompatibilidade de nomes novos com nomes antigos. Então, quando o loop estiver pronto, você poderá mover os arquivos renomeados de volta para o diretório original.

    
por 01.03.2015 / 22:06