Rename pictures in the command-line interface

nvidican at nvidican at
Mon Jan 4 20:52:16 UTC 2010

No problem. You might also consider extending it to support '.jpeg' as  
well as '.jpg', or even alter to work recursively through  
sub-directories. Like I said though, it's more or less a starting  
point. It will continue to extend beyond the current number each time  
it's run too - so it should never over-write an existing file and  
never need to be altered to support one more digit, (until system  
limitations come in to play - but that's a whole other ball game in  
terms of scale and probably the least of your worries at that point).

Personally I find things like this a LOT easier to do in Perl for the  
power and simplicity of Perls ability to handle and manipulate  
strings, (again like I'd mentioned in my original reply), I'm sure  
this is do-able in a shell script too just seems simpler to  
read/write/work with written in Perl to me and it just gets the job  

Nathan Vidican
nathan at

Quoting "Dário \"P." <fbsd.questions.list at>:

> Seg, 2010-01-04 às 14:58 -0500, nvidican at escreveu:
>> Dario,
>> I'm not personally aware of any single commands which allow
>> substitution using a counter like you're asking, or of a decent way to
>> do what you're asking from the shell script either; however,
>> personally I'd write a simple Perl script to do it. The trick being to
>> be able to find the bsd###.jpg where it left off at in a directory so
>> you don't overwrite existing files if repeatability is important.
>> Here's something quick/dirty to work with, you can build from here,
>> but try copy/pasting the following code into a new Perl script and run
>> it from withing the directory you want to work:
>> #!/usr/bin/perl -w
>> use strict;
>> my @files = `ls`; # gets a list of all files in the current dir
>> # start a counter at zero, then increment it below:
>> my $cntr=0;
>> # set counter to the largest bsd###.jpg file in this directory:
>> map { if (/^bsd(\d+)\.jpg/) { $cntr = $1 if($1>$cntr); } }
>> grep(/bsd\d+\.jpg/, at files);
>> print "Left off last time at $cntr, going to start this time at
>> ",++$cntr,".\n";
>> foreach (@files) {
>>          chomp();
>>          # skip all files which are already named bsd###.jpg
>>          # or are not in ending .jpg
>>          next if ($_ =~ /bsd\d+\.jpg/ || $_ !~ /(\.jpg)$/i);
>>          my $new = $_;
>>          # use a regular expression to substitute the name
>>          # (note /i == case insensative so it will match '.JPG' as well)
>>          $new =~ s/^(.+)\.jpg$/bsd$cntr\.jpg/i;
>>          print "Renaming $_ to $new\n";
>>          # un-comment the line below to actually do the rename:
>>          # rename($_,$new);
>>          $cntr++;
>> }
>> ### END OF SCRIPT ###
>> An example given a directory with files like:
>> blah.Jpg
>> bs432.jpg
>> bsd11.jpg
>> bsl.jpg
>> uh-oh.jpG
>> yourSelf.JPG
>> Will give you an output like:
>> Left off last time at 11, going to start this time at 12.
>> Renaming blah.Jpg to bsd12.jpg
>> Renaming bs432.jpg to bsd13.jpg
>> Renaming bsl.jpg to bsd14.jpg
>> Renaming uh-oh.jpG to bsd15.jpg
>> Renaming youSelf.JPG to bsd16.jpg
>> My $0.02 ... like anything, sure you could do this 100 different other
>> ways, and sure it's not going to be really efficient for large
>> volumes, but in a pinch it'll work pretty reliably.
>> --
>> Nathan Vidican
>> nathan at
> Worked just the way I wanted! :)
> Thank you so much for the time you spent doing this Perl script.

More information about the freebsd-questions mailing list