Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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:




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.)

share|improve this question
up vote 5 down vote accepted

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.

share|improve this answer
I 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... – MountainX Feb 20 '14 at 1:46
@MountainX, Good question, according to Wikipedia, pax has been in the Linux Standard Base since 2005. Plus the would be alternative for this, GNU cpio, is possibly the least featureful GNU tool in existence. – Graeme Feb 20 '14 at 11:49
+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. – erik Feb 20 '14 at 19:14

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

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
share|improve this answer
Thanks, could you please quote the documentation for the %%-* tip? I'm curious. – soyuka Apr 8 '15 at 16:32

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
  cp "$source" "/home/user/data/${basename%-*}.${basename##*.}"
share|improve this answer

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)
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.