2

I have a lot of images in subdirectories with same string in filename and I want to rename these files and append a suffix to their names.

Example:

1/AB2011-BLUE-BW.jpg
1/AB2011-WHITE-BW.jpg
1/AB2011-BEIGE-BW.jpg
2/AB2011-WHITE-2-BW.jpg
2/AB2011-BEIGE-2-BW.jpg
1/AB2012-BLUE-BW.jpg
1/AB2012-WHITE-BW.jpg
1/AB2012-BEIGE-BW.jpg
...

I want to rename this files in

1/AB2011-01.jpg
1/AB2011-02.jpg
1/AB2011-03.jpg
2/AB2011-04.jpg
2/AB2011-05.jpg
1/AB2012-01.jpg
1/AB2012-02.jpg
1/AB2012-03.jpg
...

How can I do this in bash or python? Which image get 01,02,03 doesn't matter.

starball
  • 20,030
  • 7
  • 43
  • 238
sokolata
  • 491
  • 3
  • 7
  • 21

2 Answers2

2

Hopefully I understood what you wanted correctly. But heres how to do it below.

# importing os module
import os
 
# Function to rename multiple files
def main():
   
    folder = "1"

    # Keeps track of count of file name based on first field 
    fileNameCountDic = {}
    
    for count, filename in enumerate(os.listdir(folder)):

        # Original path to file
        src = f"{folder}/{filename}"  # foldername/filename, if .py file is outside folder
         
        # Get first field in file name so "B2011-BLUE-BW.jpg" -> "B2011"
        firstFileNameField = filename.split("-")[0]

        # If first field in filename is not in dic set it to be the first one
        if firstFileNameField not in fileNameCountDic:
          fileNameCountDic[firstFileNameField]=1
        else: # Else inc the count
          fileNameCountDic[firstFileNameField]+=1

        # Turn file count number to String
        fileNumber = str(fileNameCountDic[firstFileNameField])
        if len(fileNumber)==1: # Add space if one digit
          fileNumber=" "+fileNumber

        # Set the new path of the file
        dst = f"{folder}/{firstFileNameField}-{fileNumber}.jpg"

        # rename() function will
        # rename all the files
        os.rename(src, dst)



main()


carlosdafield
  • 1,479
  • 5
  • 16
1

Here is an alternative implementation of renaming logic.

from collections import defaultdict
from pathlib import Path
from typing import Iterable, Iterator


FILES = [
    '1/AB2011-BLUE-BW.jpg',
    '1/AB2011-WHITE-BW.jpg',
    '1/AB2011-BEIGE-BW.jpg',
    '2/AB2011-WHITE-2-BW.jpg',
    '2/AB2011-BEIGE-2-BW.jpg',
    '1/AB2012-BLUE-BW.jpg',
    '1/AB2012-WHITE-BW.jpg',
    '1/AB2012-BEIGE-BW.jpg'
]


def rename(files: Iterable[Path]) -> Iterator[tuple[Path, Path]]:
    """Rename a file according to the given scheme."""
    
    counter = defaultdict(int)
    
    for file in files:
        name, _ = file.stem.split('-', maxsplit=1)
        counter[name] += 1
        infix = str(counter[name]).zfill(2)
        yield file, file.parent / f'{name}-{infix}{file.suffix}'


def main() -> None:
    """Rename files."""
    
    for old, new in rename(map(Path, FILES)):
        print(old, '->', new)


if __name__ == '__main__':
    main()

You can apply this to the actual file system by using e.g a glob:

from pathlib import Path


GLOB = '*/*.jpg'


def main() -> None:
    """Rename files."""

    for old, new in rename(Path.cwd().glob(GLOB)):
        old.rename(new)


if __name__ == '__main__':
    main()
Richard Neumann
  • 2,986
  • 2
  • 25
  • 50