I am wondering whether there is a way how to copy and rename a bunch of files without scripting. I have files with names like prefix_12345678901_12345678901_suffix.ext and I need to copy all of them into a given directory such that the copies are named like 1234567890_1234567890.ext

I also do not want to overwrite existing files in the target directory.

I know I could do something like:

cp -n source/*.ext target

followed by

rename 's/.*([0-9]{11}_[0-9]{11}).*\.(.*$)/$1.$2/' *.ext

but this would make copies first and only then figured out whether the files already exist or not. I need sort of a reversed process...

EDIT:

Well, I guess this is scripting, but I finally suceeded with something like:

for i in /source/*.ext; do if [[ "$i" =~ [0-9]{11}_[0-9]{11} ]]; then cp $i /target/${BASH_REMATCH[0]}.ext; fi done;

It's ok to answer your own question if you've managed to solve the problem on your own. Use the Answer your question button for that (you may have to wait a few hours to give others a chance), don't put the answer in your question.
–
GillesMay 12 '11 at 20:35

1 Answer
1

pax -rw copies files; -pp preserves permissions, and -k says not to overwrite existing files. The -s arguments tell pax to rename files as it's copying. The first transformation makes the renaming you want (using basic regular expressions and substitutions like in ed). The second transformation turns every source file name that's not yet matched into the empty string, which tells pax not to copy that file.

Note to zsh fans: as far as I can tell, you can't get zmv to copy the files where the definition doesn't exist and leave the others alone.