Com pax como encontrado no Debian, Suse, OpenBSD, NetBSD pelo menos:
find . -type f -name '*.pat' -print0 | pax -0rws'/?/_/gp' /path/to/dest/
pax é um utilitário padrão (ao contrário de tar ou cpio ), mas sua opção -0 não é, embora possa ser encontrada em algumas implementações.
Se houver dois arquivos ?.pat e _.pat , eles serão substituídos pelo mesmo nome para que um substitua o outro no destino. Mesmo se houver um diretório _ e ? , o conteúdo deles será mesclado dentro do diretório _ no destino.
Com o GNU sort e o GNU uniq , você pode verificar os conflitos antecipadamente com:
find . -type f -name '*.pat' -print0 |
tr '?' _ |
sort -z |
uniq -zd |
tr 'autoload zmv
mkdir-and-cp() {mkdir -p -- $3:h && cp $@}
zmv -n -Qp mkdir-and-cp '(**/)*.pat(D.)' '/path/to/dest/$f:gs/?/_/'
' '\n'
Qual seria o relatório de arquivos conflitantes (mas não diretórios).
Você pode usar zsh zmv , o que resolveria os conflitos, mas isso ainda significaria um mkdir e um cp por arquivo:
find . -type f -name '*.pat' -print0 | pax -0rws'/?/_/gp' /path/to/dest/
(remova -n quando feliz).