What is the command for renaming file extensions from uppercase to lowercase?
Example:
hello.JPG
hi.JPG
to:
hello.jpg
hi.jpg
What is the command for renaming file extensions from uppercase to lowercase?
Example:
hello.JPG
hi.JPG
to:
hello.jpg
hi.jpg
If you know what file extensions you're dealing with, you can hard-code it:
for f in *.JPG
do
mv "$f" "${f%.JPG}.jpg"
done
For the more-general case:
for f in *
do
e="${f##*.}"
b="${f%.*}"
mv "$f" "${b}.${e,,}"
done
Where the heavy lifting is done with bash variable expansion to:
,,
) in the processrename ' -f and /[A-Z][^.]*$/ and s/\.[^.]+$/\L$&/' *
rename ' -f and s/\.[^.]*[A-Z][^.]*$/\L$&/' *
We need to realize that, under the hood, rename
is just Perl
code. Think of it as: the wildcard *
feeds the names to this code in a loop
and on each of these names we perform the following actions:
$_
) is a regular file ( file-test operator -f
filename, when filename is omitted, it defaults to $_
) Note: To prevent rename
from thinking that the -f
we want for our file-test is an option to it we use a space before the -f
to preclude that possibility!!!/[A-Z][^.]*$/
This looks at an unbroken run of non-dot characters seen from the filename's end to assert that at least one uppercase is present in the extension portion of the filename. It might so happen, that there's no extension to speak of. This fact is taken care of in the next step, where we look for a literal .
in the filename as well.s/\.[^.]+$/\L$&/
isolates the complete extension portion in the current filename by looking from the filename's end and looking left and grabbing all non-dot [^.]+
characters till the time a literal \.
is seen. The \L$&
will turn all the uppercase -> lower in the matched text.s///
command itself of checking an uppercase in extension.m//
and s///
normally run on an attached string via the =~
operator, as say, $var =~ m/[A-Z]+/
$filenm =~ s/ABC/DEF/
. But in case the variable in question happens to be the $_
then we can dispense with the =~ and write it simply m/[A-Z]+/
s/ABC/DEF/
will imply the variable on which these regexes operate is the $_
. Also, we can dispense with the m
in case of m//
when the delimiters are slashes. We however, do need it in case of say m{}
m||
etc. This is a very common idiom in Perl
style.Just to add another answer which isn't yet listed:
for f in *.JPG; do mv "$f" "${f//JPG/jpg}"; done
"${f//.JPG/.jpg}"
– Jeff Schaller
May 19 '17 at 15:26