0

I have a folder containing .png images that are named image1.png, image2.png, image3.png etc.

The way this folder is organized, 3 consecutive images represent data from the same subject, so I'd like them to be named with the same identifying number + a letter to differentiate them. Like this:

image1.png --> 1-a.png
image2.png --> 1-b.png
image3.png --> 1-c.png
image4.png --> 2-a.png
image5.png --> 2-b.png
image6.png --> 2-c.png

and so on.

What would be the best way to do this? a Perl script? or generating a .txt in python with the desired names and then using it to rename the files? I'm using Ubuntu.

Thanks in advance!

gantry
  • 13
  • 2
  • 1
    Almost any scripting language would be sufficient. Why not give it a try and see how you get along? – Sobrique Mar 06 '19 at 13:29
  • the script should handle sorting logic as well or you can make it sort in certain order? Because we don't know what is exactly the filename pattern. You mentioned `image01` and `image1` in your question – Kent Mar 06 '19 at 13:53
  • @Kent The files are already sorted, and there are no leading zeros. Thanks for pointing that out - I just edited the question. – gantry Mar 06 '19 at 14:01

4 Answers4

1

Given a file list files in Python, you can use itertools.product to generate your desired pairings of numbers and letters:

from itertools import product
import os

os.chdir(directory_containing_images)
# instead of hard-coding files you will actually want:
# files = os.listdir('.')
files = ['image1.png', 'image2.png', 'image3.png', 'image4.png', 'image5.png', 'image6.png']
for file, (n, a) in zip(files, product(range(1, len(files) // 3 + 2), 'abc')):
    os.rename(file, '{}-{}.png'.format(n, a))

If you replace os.rename with print, the above code will output:

image1.png 1-a.png
image2.png 1-b.png
image3.png 1-c.png
image4.png 2-a.png
image5.png 2-b.png
image6.png 2-c.png
blhsing
  • 91,368
  • 6
  • 71
  • 106
  • I ended up going with this solution. I had to add human/natural sorting to fix order issues such as `image1.png` being followed by `image10.png`. This question was helpful for that: https://stackoverflow.com/questions/5967500/how-to-correctly-sort-a-string-with-a-number-inside – gantry Mar 06 '19 at 15:36
0

In perl you could do:

my @new_names = map {
    my ( $n ) = $_ =~ /image(\d+)\.png/;
    my $j = (($n - 1)  % 3) + 1;
    my $char = (qw(a b c))[ int( $n / 3 ) ];
    "$j-$char.png"
} @files;

This assumes no special ordering of the @files array.

Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
0

Fun project. :)

declare -i ctr=1 fileset=1              # tracking numbers
declare -a tag=( c a b )                # lookup table
for f in $( printf "%s\n" *.png |       # stack as lines
            sort -k1.6n )               # order appropriately
do ref=$(( ctr++ % 3 ))                 # index the lookup
   end=${f##*.}                         # keep the file ending
   mv "$f" "$fileset-${tag[ref]}.$end"  # mv old file to new name
   (( ref )) || (( fileset++ ))         # increment the *set*
done

mv image1.png 1-a.png
mv image2.png 1-b.png
mv image3.png 1-c.png
mv image4.png 2-a.png
mv image5.png 2-b.png
mv image6.png 2-c.png
mv image7.png 3-a.png
mv image8.png 3-b.png
mv image9.png 3-c.png
mv image10.png 4-a.png
mv image11.png 4-b.png
mv image12.png 4-c.png

Obviously, edit as needed for pathing &c.

Paul Hodges
  • 13,382
  • 1
  • 17
  • 36
0

I tried this in python3 and its working as per your need.

import os
import string
os.chdir(path_to_your_folder)
no=1
count=1
alphabet = ['a','b','c']
count=0
for filename in os.listdir(os.getcwd()):
    newfilename = (str(no) + "-" + alphabet[count]+".png")
    os.rename(filename,newfilename)
    count=(count+1)%3
    if count==0:
        no=no+1