OK, então consegui me safar com o antigo sed como este.
ls -1 \
storage/{innobase,xtradb}/pars/{pars0grm.cc,pars0grm.y,pars0lex.l,lexyy.cc} \
storage/{innobase,xtradb}/fts/{fts0blex.cc,fts0blex.l,fts0pars.cc,fts0pars.y,fts0tlex.cc,fts0tlex.l} \
storage/innobase/include/fts0[bt]lex.h \
| sed -re 'h; s|/pars/|/|; s|/fts/|/|; s|innobase/include|include|; H; x; s|\n| |' \
| xargs -L1 cp -v \
;
O script sed não é tão trivial, portanto, deixe-me explicar passo a passo (para o futuro eu):
-
h copia a linha atual ("espaço de padrão") em um registrador ("espaço de espera");
- cada
s edita o espaço padrão como de costume, o espaço reservado não muda;
-
H acrescenta a linha agora editada ao registrador de espera - que contém duas linhas, o nome do arquivo antigo e o novo, com caracteres \n embutidos, claro ;
-
x troca o espaço de armazenamento com espaço de padrão, carregando efetivamente o par antigo-novo do registrador de espera;
-
s|\n| | achata as duas linhas em uma, separando-as com espaço;
- e, finalmente, um
p implícito (da chamada sed sem -n ) imprime o resultado.
No total, o pipeline funciona da seguinte maneira:
-
ls -1 expande todos os globs em nomes de arquivos reais existentes e os imprime um por linha;
-
sed transforma isso em "$old_filename $new_filename" , novamente um arquivo por linha;
-
xargs -L1 chama cp -v $old_filename $new_filename em todas as linhas.
É isso aí!