2

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

name_YYMM.csv

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

name_YYYYMM.csv

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

2
  • 1
    There are batch file renaming utilities available through the Ubuntu software centre, have you tried any of these?
    – Tog
    Dec 10, 2010 at 11:26
  • I don't know how to do it without a bash script Dec 10, 2010 at 11:30

3 Answers 3

2

A very simple way to do it

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

or

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.

4
  • 'name' is a place holder. On my disk the files are named <name>_YYMM.csv, where <name> is an alphanumeric string.
    – Takashi
    Dec 10, 2010 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, 2010 at 13:35
  • It worked! thanks. Now, ... to try to understand what kind of magic we are dealing with here ;)
    – Takashi
    Dec 10, 2010 at 14:17
  • 1
    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. Dec 10, 2010 at 16:48
1

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
0

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.

You must log in to answer this question.

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