How to loop through multiple subdirectories and change file extension

I was assigned to manage a legacy codeIgniter 3 code base. There is this error that the website doesn’t load images that are .JPG. Rather than making it not case-sensitive we want to change every .JPG to .jpg. This is the file structure:

- 0
- 1
- 10
- 100
- 101
    - 0
    - 1
    - 10
    - 11
        - 10111
            - image.JPG
            - image-small.jpg
            - ...
    - 12
    - ...
- 102
- ...

I know how to loop through files, and replace the extensions, but not sure how to loop through this many folders.

This code would be for replacing the extension for file in *.JPG; do mv -- "$file" "${f%.JPG}.jpg"; done

use the extended globbing in your shell:

# not needed in ZSH, but in bash 
shopt -s globstar

# note the **/:
for file in **/*.JPG; do
  mv -- "$file" "${file%.JPG}.jpg"
done
Answered By: Marcus Müller

Using Perl’s rename (on Linux it may be called differently depending on the distribution / I’m unfamiliar with the naming on BSD) you may do (remove the -n switch if you’re happy with the result to actually perform the renaming):

shopt -s globstar
rename -n 's/.JPG$/.jpg/' **/*.JPG

Or, more interestingly, to lowercase any number of extensions specified via globbing patterns (supporting also extensions such as .EXT1.EXT2):

shopt -s globstar
rename -n 's/(.*/.*?.)(.*)/$1L$2/' **/*.JPG **/*.EXT1.EXT2

Which by default won’t clobber files already existing in target’s directory (such as it would happen in the case of file.JPG and file.jpg in the same directory):

% tree
.
└── foo
    └── bar
        ├── file.EXT1.EXT2
        ├── file.jpg
        └── file.JPG

3 directories, 3 files
% rename 's/(.*/.*?.)(.*)/$1L$2/' **/*.JPG **/*.EXT1.EXT2
foo/bar/file.JPG not renamed: foo/bar/file.jpg already exists
% mv foo/bar/file.jpg foo/bar/file1.jpg
% rename 's/(.*/.*?.)(.*)/$1L$2/' **/*.JPG **/*.EXT1.EXT2
% tree
.
└── foo
    └── bar
        ├── file1.jpg
        ├── file.ext1.ext2
        └── file.jpg

3 directories, 3 files
Answered By: kos
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.