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;
Best Answer
pax
can copy and rename all at once.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 ined
). 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.