Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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

So I am supposed to find all the files in the given directory with surffix of .C or cc, and change their name to .C.blah or .cc.blah

Is there a command to do that?

Or should I implement this with the command find?

share|improve this question
What have you tried already (assuming this is homework)? – soandos Jan 18 '12 at 5:01
I have actually sorted this out by using the find command, by implementing the -execdir option and mv command, but I still need to play around with it. – Anson Jan 18 '12 at 5:24
So it will be great if someone can still answer this question with an full answer – Anson Jan 18 '12 at 5:31
After all the Wiking and googling, I now have the answer to my own question =] I can use find to execute command on the files returned by find directly. with the -exec option so it will be find . -type f ( -name ".C" -o -name ".cc" ) -exec mv {} {}.blah\;} – Anson Jan 18 '12 at 6:19

There are a few approaches, depending on what is available on your *nix.

There two different rename commands around, one provided through perl, and one as part of standard utils.

Perl version:

rename 's/(\.cc$|\.C$)/$1.blah/' *.cc *.C

utils version - you might be able to do this with one line:

rename .C .C.blah *.C
rename .cc .cc.blah *.cc

for loop:

for i in *.C *.cc ; do mv $i $i.blah ; done
share|improve this answer

I know you already found your own acceptable solution, but I want to post what I would normally use at work. This syntax works for GNU findutils, which is part of any modern linux distro.

## xargs is much faster than -exec, xargs can run parallel on # cores with -P #
find ./ -type f -name '*.C' -o -name '*.cc' | xargs -I '{}' mv '{}' '{}'.BAK

##  If I'm specifying more than two extensions, I would generally use a regex
find ./ -type f -regex ".*\.\(C\|cpp\)$" | xargs -I '{}' mv '{}' '{}'.BAK

Especially with the now common quad-core SMP servers, you can usually half running time with -p 4. Even with only one core, xargs avoids the extraneous forking find ...-exec would initiate. With a desktop, and unlimited time, it's not really a problem. On the other hand using server resources, and working with many thousands of files, avoiding unnecessary overhead is a priority.

share|improve this answer

use a simple for-loop:

for file in *.txt; do echo $file $file.blah; done

This command echoes the old file name and the new file to the terminal. If you're getting expected results, go for the real command:

for file in *.txt; do mv $file $file.blah; done

Anyway, this won't rename *.txt files in subdirectories. Use find for it.

share|improve this answer

There are two different rename commands.

On Ubuntu/Debian/... distros:

rename -v 's/$/.blah/' *.C *.cc

On RedHat/CentOS/... distros:

rename -v $ .blah *.C *.cc
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.