how to rename files while copying?
Solution 1
pax
can do this all at once. You could do:
cd /backup/path/data && pax -wrs'/-.*$/.etf/' Erp*etf /home/user/data
pax
preserves times by default, but can add -pe
to preserve everything (best done as root) or -pp
to preserve permissions , eg:
cd /backup/path/data && pax -wrs'/-.*$/.etf/' -pe Erp*etf /home/user/data
Otherwise (pax
isn't usually available by default), surely it is better to do a copy then a rename
:
cp -a /backup/path/data/Erp*.etf /home/user/data
rename 's/-.*$/.etf/' /home/user/data/Erp*.etf
This way there is not a different process started for each file.
Solution 2
You can use the cp
command with the -a
option
-a, --archive
same as -dR --preserve=all
And then use a for loop to rename all files while copying them:
for file in Erp*etf; do
cp -a $file destinationDirectory/${file%%-*}.etf
done
Ready. Start this command in the source directory.
Explanation: The %%-*
will cut off all the characters after the first occurence of a hyphen/minus -
and the .etf
at the end again adds the file extension.
Well, and as a one liner, put it all in one line. :-) Like this
for file in Erp*etf; do cp -a $file destinationDirectory/${file%%-*}.etf; done
Solution 3
In zsh, use zmv
. Put this in your .zshrc
:
autoload -U zmv
alias zcp='zmv -C'
alias zln='zmv -L'
Then use
zcp '/backup/path/data/(*)-[0-9A-Fa-f_]#.(*)' '/home/user/data/$1$2'
In bash:
zsh -c 'autoload zmv; zmv -C $0 $1' '/backup/path/data/(*)-[0-9A-Fa-f_]#.(*)' '/home/user/data/$1$2'
If you don't have zsh, a POSIX way uses pax (this copies directories recursively).
If you're on a restricted system with no zsh and no pax, you can use a loop:
for source in /backup/path/data/*-*.etf; do
basename=${source##*/}
cp "$source" "/home/user/data/${basename%-*}.${basename##*.}"
done
Solution 4
cp
doesn't have that capability. I recall cpio
being able to do that, but the current manpage says otherwise. However, (gnu) tar
does have a --transform
option:
--transform, --xform EXPRESSION
use sed replace EXPRESSION to transform file names
So you'd have a cmdline like:
(cd /backup/path/data; tar --create --transform 's/-.*-....//' .) | (cd /home/user/data; tar --extract)
Related videos on Youtube
Jarek
You may be interested in the story of SE moderator Monica Cellio and how she was unfairly treated by the corporate management of this site. More info here. An update is available. Let's hope we can cultivate a more fair environment for content creators and moderators going forward.
Updated on September 18, 2022Comments
-
Jarek almost 2 years
How would I copy (archive style where date isn't changed) all the files in a backup directory to the user's directory while renaming each file to remove the random string portion from the name (i.e., -2b0fd460_1426b77b1ee_-7b8e)?
cp from:
/backup/path/data/Erp.2014.02.16_16.57.03-2b0fd460_1426b77b1ee_-7b8e.etf
to:
/home/user/data/Erp.2014.02.16_16.57.03.etf
Each file will always start with "Erp." followed by the date-time stamp string followed by the random string and then the extension ".etf". I want to keep all name elements including the date-time stamp. I just want to remove the random string.
The random string allows multiple backups of the same file. However, in this case, I just ran fdupes and there are no duplicates. So I can simply restore all the files, removing the random string.
I'm looking for a one-line bash command to do it.
If that won't work, I could do it in two or more steps. I normally use KRename, but in this case I need to do it in bash. (I'm working remotely.)
-
Jarek over 10 yearsI can see that I need to become familiar with
pax
. This looks like a very useful tool. Makes me wonder why it isn't standard in more distros... -
Graeme over 10 years@MountainX, Good question, according to Wikipedia,
pax
has been in the Linux Standard Base since 2005. Plus the would be alternative for this, GNUcpio
, is possibly the least featureful GNU tool in existence. -
erik over 10 years+1 for your last solution and This way there is not a different process started for each file. But
rename
is different on Fedora/Red Hat: I don’t know how to use it in this case. -
soyuka about 9 yearsThanks, could you please quote the documentation for the
%%-*
tip? I'm curious.