Digamos que você tenha (a, b, c) .foo e (p, q, r) .bar:
ls
a.foo b.foo c.foo p.bar q.bar r.bar
Você coleta os foos e as barras nas variáveis da matriz:
foos=(*.foo)
bars=(*.bar)
O tamanho de uma matriz é $ {# foos [*]}, os índices vão de 0 a len-1. O primeiro elemento é $ {foos [0]} ou $ {bars [0]}.
for f in $(seq 0 $((${#foos[*]}-1)))
do
fool=${foos[$f]};
echo mv ${bars[$f]} ${fool%.foo%.bar}
mv ${bars[$f]} ${fool/.foo/.bar}
done
mv p.bar a.bar
mv q.bar b.bar
mv r.bar c.bar
Se você não gosta do eco, remova-o. O script pressupõe um número correspondente de arquivos foo e bar. Eu não tenho certeza se as linhas 3 e 4 sempre listarão os nomes em ordem alfabética - ele fez em meus testes, mas eu não tenho uma especificação escrita para isso.
Se o arquivo contiver um arquivo adicional ".foo", como "a.foo-bork.foo", ele não funcionará como conjunto de intenções e não será limpo contra espaços em branco em nomes de arquivos ou linebreakes e afins. Mas pode fazer o que você quiser.