Existe um comando padrão pouco conhecido no Unix que pode nos ajudar a encontrar uma solução geral para encontrar em qual ordem uma série de renomeações deve ser feita: tsort
Digamos que tenhamos uma lista de renomeações a serem feitas em um arquivo chamado renames.txt
(assumindo por causa da demonstração que seu nome não contém espaços em branco):
d a
e f
b e
a c
Como d
deve ser renomeado para a
, isso significa que a
deve ser renomeado antes de d
. Então, temos uma ordem de classificação parcial, que seria o contrário da ordem em que os arquivos deveriam ser renomeados.
tsort
é a ferramenta para inferir uma ordem de classificação completa de uma lista de ordens de classificação parciais. Ele retornaria com um erro se houvesse um loop que nos ajudaria a detectar casos em que não há solução. Se aplicarmos tsort
nessa entrada, isso nos dará:
b
d
e
a
f
c
O que diz que b
deve ser renomeado após d
após e
. Podemos usar GNU tac
(alguns sistemas também têm tail -r
) para reverter essa ordem:
c
f
a
e
d
b
Junte-se a ele com nossa lista de renomeações:
tsort renames.txt | tac | awk '
NR==FNR {
ren[$1] = $2
next
}
$1 in ren {
print "mv -i --", $1, ren[$1]
}' renames.txt -
que nos dá:
mv -i -- a c
mv -i -- e f
mv -i -- d a
mv -i -- b e
que podemos então canalizar para sh
para executar.
No entanto, observe que o código acima não é robusto, pois não verificamos o status de saída de tsort
acima para detectar loops e os nomes de arquivos não devem conter nenhum caractere de shell especial.
A robificação é deixada como um exercício para o leitor; -)