views:

94

answers:

2

Hey all,
    I have a bunch of sequentially named files in this format: imageXXX.jpg. So it would be like image001.jpg and onward. I just want to keep the number part of this, and get rid of the prepended 0's. So instead, that file would be named 1.jpg. How could I achieve this using BASH?

Thanks!
  -Trey

+2  A: 

On Linux the venerable Perl utility rename is friendly:

$ rename 's/^image0+//' image*.jpg

You should be aware that stripping leading zeros will ruin the sort order, that is *.jpg orders like:

1.jpg
10.jpg
11.jpg
...
2.jpg
20.jpg

If you want to keep the order just use

$ rename 's/^image//' image*.jpg

instead.

added in response to system identification

You can likely script it in bash alone, but it would be non-trivial and the failure cases really need to be handled correctly. Yeah, hoisting Perl onto a system is non-trivial too, but it is easy and that wheel's already been invented

Fedora Core 8 Perl RPM: http://rpm.pbone.net/index.php3/stat/4/idpl/5152898/dir/fedora_8/com/perl-5.8.8-30.n0i.51.fc8.i386.rpm.html
CPAN rename: http://search.cpan.org/~rmbarker/File-Rename-0.05/

added in response to silent failure

rename like chmod will complain if you give it malformed arguments, but both are silent if what you request has no effect. For example

$ ls -l junk
-rw-r--r-- 1 msw msw 0 2010-09-24 01:59 junk
$ chmod 688 junk
chmod: invalid mode: '688'
$ chmod 644 junk    # was already 644 mode, nothing happened no error
$ rename 's/bob/alice/' ju*k    
# there was no 'bob' in 'junk' to substitute, no change, no error
$ ls -l junk
-rw-r--r-- 1 msw msw 0 2010-09-24 01:59 junk
$ rename 's/un/ac/' j*k  # but there is an 'un' in 'junk', change it
$ ls -l j*k
-rw-r--r-- 1 msw msw 0 2010-09-24 01:59 jack

You can make rename less silent:

$ rename --verbose 's/ac/er/' j*k
jack renamed as jerk
$ rename --verbose 's/ac/er/' j*k   # nothing to rename
$                  
msw
Many thanks for the help, but for some reason it didn't seem to rename the files on our server. The command you posted above failed silently.
TreyK
+2  A: 

Pure Bash:

shopt -s extglob
for f in image*.jpg; do mv "$f" "${f/#image*(0)}"; done

Additional code could check for name collisions or handle other error conditions. You could use mv -i to prompt before files are overwritten.

Dennis Williamson
This got the job done! Thanks!
TreyK
+1: giving the people what they ask for. @TreyK, this does one trick, rename and the commands it takes does the next job and plenty others too. Moreover, the Perl `s`/ubstit/ute/ command used is seen throughout Unix tools; you'll probably see it again.
msw