Convert All File Extensions to Lower-Case

Convert all file extensions to lower-case

Solution

You can solve the task in one line:

find . -name '*.*' -exec sh -c '
a=$(echo "$0" | sed -r "s/([^.]*)\$/\L\1/");
[ "$a" != "$0" ] && mv "$0" "$a" ' {} \;

Note: this will break for filenames that contain newlines. But bear with me for now.

Example of usage

$ mkdir C; touch 1.TXT a.TXT B.TXT C/D.TXT
$ find .
.
./C
./C/D.TXT
./1.TXT
./a.TXT
./B.TXT

$ find . -name '*.*' -exec sh -c 'a=$(echo "$0" | sed -r "s/([^.]*)\$/\L\1/"); [ "$a" != "$0" ] && mv "$0" "$a" ' {} \;

$ find .
.
./C
./C/D.txt
./a.txt
./B.txt
./1.txt

Explanation

You find all files in current directory (.) that have period . in its name (-name '*.*') and run the command for each file:

a=$(echo "$0" | sed -r "s/([^.]*)\$/\L\1/");
[ "$a" != "$0" ] && mv "{}" "$a"

That command means: try to convert file extension to lowercase (that makes sed):

$ echo 1.txt | sed -r "s/([^.]*)\$/\L\1/"
1.txt
$ echo 2.TXT | sed -r "s/([^.]*)\$/\L\1/"
2.txt

and save the result to the a variable.

If something was changed [ "$a" != "$0" ], rename the file mv "$0" "$a".

The name of the file being processed ({}) passed to sh -c as its additional argument and it is seen inside the command line as $0.
It makes the script safe, because in this case the shell take {} as a data, not as a code-part, as when it is specified directly in the command line.
(I thank @gniourf_gniourf for pointing me at this really important issue).

As you can see, if you use {} directly in the script,
it's possible to have
some shell-injections in the filenames, something like:

; rm -rf * ;

In this case the injection will be considered by the shell as a part of
the code and they will be executed.

While-version

Clearer, but a little bit longer, version of the script:

find . -name '*.*' | while IFS= read -r f
do
a=$(echo "$f" | sed -r "s/([^.]*)\$/\L\1/");
[ "$a" != "$f" ] && mv "$f" "$a"
done

This still breaks for filenames containing newlines. To fix this issue, you need to have a find that supports -print0 (like GNU find) and Bash (so that read supports the -d delimiter switch):

find . -name '*.*' -print0 | while IFS= read -r -d '' f
do
a=$(echo "$f" | sed -r "s/([^.]*)\$/\L\1/");
[ "$a" != "$f" ] && mv "$f" "$a"
done

This still breaks for files that contain trailing newlines (as they will be absorbed by the a=$(...) subshell. If you really want a foolproof method (and you should!), with a recent version of Bash (Bash≥4.0) that supports the ,, parameter expansion here's the ultimate solution:

find . -name '*.*' -print0 | while IFS= read -r -d '' f
do
base=${f%.*}
ext=${f##*.}
a=$base.${ext,,}
[ "$a" != "$f" ] && mv -- "$f" "$a"
done

Back to the original solution

Or in one find go (back to the original solution with some fixes that makes it really foolproof):

find . -name '*.*' -type f -exec bash -c 'base=${0%.*} ext=${0##*.} a=$base.${ext,,}; [ "$a" != "$0" ] && mv -- "$0" "$a"' {} \;

I added -type f so that only regular files are renamed. Without this, you could still have problems if directory names are renamed before file names. If you also want to rename directories (and links, pipes, etc.) you should use -depth:

find . -depth -name '*.*' -type f -exec bash -c 'base=${0%.*} ext=${0##*.} a=$base.${ext,,}; [ "$a" != "$0" ] && mv -- "$0" "$a"' {} \;

so that find performs a depth-first search.

You may argue that it's not efficient to spawn a bash process for each file found. That's correct, and the previous loop version would then be better.

How do I de-capitalize all file extensions given a directory?

Use the ToLower() method of the String class, and the ChangeExtension() method of the Path class. This should allow you to lowercase all of the extensions without having to enumerate every possible extension.

DirectoryInfo folder = new DirectoryInfo("c:\whatever");
FileInfo[] files = dirInfo.GetFiles("*.*");

foreach (var file in files)
{
File.Move(file.FullName, Path.ChangeExtension(file,
Path.GetExtension(file).ToLower()));
}

Batch rename extension to lowercase

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"

FOR /f "delims=" %%A IN (
'dir /b /a-d "%sourcedir%\*" '
) DO (
FOR /f "delims=" %%a IN (
'dir /b /l "%sourcedir%\%%A" '
) DO (
if "%%~xa" neq "%%~xA" ECHO REN "%sourcedir%\%%A" "%%~nA%%~xa"
)
)

GOTO :EOF

Naturally, the two nested for commands may be compacted to a single line if desired - shown here on multiple lines for legibility.

You would need to change the setting of sourcedir to suit your circumstances.

The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO REN to REN to actually rename the files.

Note that %%A retains the original character-case but %%a (a completely different variable) acquires the lower-case equivalent because of the /l switch on the dir command.


Following Aacini's response, more extensive testing (well, actually trying to rename files rather than just generate a rename instruction that should on first glance work) revealed this doesn't actually work, possibly because the OS sees a file being renamed to its own name (disregarding case). Hmph.

So - first step was to rename twice - first to a dummy name, and then from the dummy name to the required name.

Fine in theory. Problem was that the ~x operator doesn't seem to consistently report the same string - almost depending on how many times it's used. So - I tried executing a subroutine, passing the "to" and "from" filenames. The subroutine seemed to have the same problems when attempting to access the name fragments of the parameters. Gloom.

So I assigned the name to a variable and tried processing that. Repeatedly remove the string before . in the name until there are no more dots and you have the extension.

Then remove the extension from the filename, but can't use the replace-with-nothing method since the filename may be whatever.txt.txt for instance. So lop off the last few characters one at a time within a loop for the length of the extension found+1 (for the dot).

So - if the lower-case version of the extension found is the same as the current-case version in ext2, no rename required. Otherwise, rename to the original-case name+the lower-case extension. Via a dummy name to ensure the OS doesn't get too smart for itself.

And here's the result. Subject to unexpected results with the usual characters, of course.

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
:choosedummy
SET "dummyname=dummyname.%random%"
IF EXIST "%sourcedir%\%dummyname%" GOTO choosedummy

FOR /f "delims=" %%A IN (
'dir /b /a-d "%sourcedir%\*" '
) DO (
FOR /f "delims=" %%a IN (
'dir /b /l "%sourcedir%\%%A" '
) DO CALL :casechg "%%a" "%%A"
)

GOTO :EOF

:casechg
SET "ext2=%~2"
SET "name2=%~2"
:ext2loop
IF "%ext2%" neq "%ext2:*.=%" SET "ext2=%ext2:*.=%"&GOTO ext2loop

:: if extension cases are identical, or no extension, skip rename
IF "%~x1" equ "" GOTO :EOF
IF "%~x1" equ ".%ext2%" GOTO :EOF

SET "lop=%ext2%"
:loploop
SET "name2=%name2:~0,-1%"
IF DEFINED lop SET "lop=%lop:~1%"&GOTO loploop

REN "%sourcedir%\%~2" "%dummyname%"
REN "%sourcedir%\%dummyname%" "%name2%%~x1"
GOTO :eof

Most Pythonic and fastest way to change a file name extension, if it's uppercase, to lower case

if you want lowercase all of the extensions, not just 'PDF', or/and have some more control on renaming most simple, intuitive and self-descriptive base of solution is

def lowercase_exts(folder):
for fname in os.listdir(folder):
name, ext = os.path.splitext(fname)
os.rename(os.path.join(folder, fname), os.path.join(folder, name + ext.lower()))

But if you need just efficiently rename millions of pdf on windows

import os
import subprocess

os.chdir(folder)
subprocess.call('ren *.PDF *.pdf', shell=True)

Where in the code can I change file extension to lowercase before uploading?

The proper way to change a file name in Fine Uploader would be to use the setName API method inside of a submit event handler.

For example, to ensure all file extensions are lower-case:

var uploader = new qq.FineUploader({
/* other required config options left out for brevity */

callbacks: {
onSubmit: function(id, name) {
var extension = qq.getExtension(name);
if (extension != null) {
var newName = name.replace(new RegExp('\\.' + extension + '$'), extension.toLowerCase());
this.setName(id, newName);
}
}
}
});

File extension is change upper case to lower case in codeigniter

please change CI system library

default in CI upload library $file_ext_tolower = FALSE.

.system\libraries\upload.php

public $file_ext_tolower = TRUE;

How can I change a R script file to a lowercase r file extension?

R can do it the following way:

x <- list.files(pattern = "\\.R$") # make sure to set working directory first
file.rename(x, sub("R$", "r", x))

Android: Convert .extensions to Lower/Upper case

A simple attachemtnDescription.toString().toUpperCase().endsWith(".JPG") will solve your problem, convert the file name to uppercase/lowercase before do the comparison.



Related Topics



Leave a reply



Submit