Super User is a question and answer site for computer enthusiasts and power users. 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

I have files in a directory. The file names are constructed using a date timestamp notation, the file names are of the form:


I want to rename all such files using the following naming convention:


I am not sure if I can use a command line utility like grep to do this, or if I need to write a bash script to do this.

Any help on how to solve this prob will be appreciated.

I am running on Ubuntu

share|improve this question
There are batch file renaming utilities available through the Ubuntu software centre, have you tried any of these? – Tog Dec 10 '10 at 11:26
I don't know how to do it without a bash script – RobotHumans Dec 10 '10 at 11:30
up vote 2 down vote accepted

A very simple way to do it

ls name* | while read a; do mv $a `echo $a | sed s/name_/name_20/`; done


ls name* | while read a; do mv $a $(echo $a | sed s/name_/name_20/); done

(since use of back-quotes is depreciated (or hard to read anyway))

it lists all files matching name_ then for each file it finds it replaces name_ with name_20. You can change 20 to 19 if you are working with files from the last millennium.

share|improve this answer
'name' is a place holder. On my disk the files are named <name>_YYMM.csv, where <name> is an alphanumeric string. – Takashi Dec 10 '10 at 13:24
@Takashi - If <name> does not contain any underscores (_) it's still simple. Just substitute name_ for _ in the above example and replace ls name* with ls *.csv – Nifle Dec 10 '10 at 13:35
It worked! thanks. Now, ... to try to understand what kind of magic we are dealing with here ;) – Takashi Dec 10 '10 at 14:17
It would be better to use a for loop without ls. Variables that contain filenames (and, similarly, command substitution that processes filenames) should always be quoted. – Dennis Williamson Dec 10 '10 at 16:48

It is likely that you have a program or Perl script called rename on your system.

For the Perl script version:

rename 's/_/_20/' *_*.csv

For the util-linux-ng version:

rename _ _20 *_*.csv

Or, using Bash:

for f in name*; do mv "$f" "${f/_/_20}"; done
share|improve this answer

In zsh:

autoload zmv
zmv '(*_[0-9][0-9])([0-9][0-9].csv)' '${1}20${2}'

You can make the pattern less precise, e.g. '(*_??)(??.csv)' or even '(*)(??).csv' if there's no risk of other files matching.

If you don't want to use zsh, see Dennis Williamson's answer.

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .