How do I rename all folders and files to lowercase on Linux?
A concise version using the "rename"
command:
find my_root_dir -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;
This avoids problems with directories being renamed before files and trying to move files into non-existing directories (e.g. "A/A"
into "a/a"
).
Or, a more verbose version without using "rename"
.
for SRC in `find my_root_dir -depth`
do
DST=`dirname "${SRC}"`/`basename "${SRC}" | tr '[A-Z]' '[a-z]'`
if [ "${SRC}" != "${DST}" ]
then
[ ! -e "${DST}" ] && mv -T "${SRC}" "${DST}" || echo "${SRC} was not renamed"
fi
done
P.S.
The latter allows more flexibility with the move command (for example, "svn mv"
).
How to change filenames to lowercase?
for file in *; do
[[ -f "$file" ]] && mv "$file" "${file,,}" 2>/dev/null
done
I'm not sure what version of bash introduced the ${var,,}
expansion.
How to rename only the parent folder to lowercase using command line?
You can tweak it like this:
cd file_groups
find . -type d -maxdepth 1 -exec rename 's/(.*)/\L$1/' {} \;
-maxdepth 1
will only go one level deep to find directories
Convert folder and file names to camel case
You can use the regular expression aptitude to deal with upper and lower case translations, regarding your current local collation (LC_ALL
, check with the locale
command).
If your filename's "words" are separated with a space and are all in lower case, you can use a simple shell script like this :
#!/bin/sh
while read -r FILENAME ; do
NEWNAME="`echo \"${FILENAME}\" | sed 's/ *\([^ ]\)/\u\1/g'`"
if [ ! "${NEWNAME}" ] ; then
NEWNAME="${FILENAME}";
fi
if [ "${FILENAME}" = "${NEWNAME}" ]; then
printf "No change : %s\\n" "${FILENAME}" >&2;
else
if [ -e "${NEWNAME}" ] ; then
printf "Already changed : %s => %s\\n" "${FILENAME}" "${NEWNAME}" >&2;
else
echo "mv \"${FILENAME}\" \"${NEWNAME}\"";
fi
fi
done
Remove the echo
on echo "mv \"${FILENAME}\" \"${NEWNAME}\"";
to do the mv.
Note that it should work fine with accented letters or any unicode letter having lower and upper code.
The script takes the file list to operate from stdin
, so to use it "as is", you can use something like the following examples :
find . -type 'f' | theScript.sh
For a whole tree of files.
For folders, you'll have to operate them separately. List them and sort them in a descending order.ls -1 | theScript.sh
For files in the current folder.
If your files may have all or partial upper cases at start and you look to force them entirely to camel case, you can change the line :
NEWNAME="`echo \"${FILENAME}\" | sed 's/ *\([^ ]\)/\u\1/g'`"
With:
NEWNAME="\`echo \"${FILENAME}\" | sed 's/\(.*\)/\l\1/;s/ *\([^ ]\)/\u\1/g'\`"
rename all the files in the current directory whose name conatains upper-case into all lower case
You are not passing any data into the tr
program, and you are not capturing any output either.
If you are using sh
:
for f in *[A-Z]*
do
if [ -f "$f" ]; then
new_name=$(echo "$f"|tr 'A-Z' 'a-z')
mv "$f" "$new_name"
fi
done
Note the indentation - it makes code easier to read.
If you are using bash
there is no need to use an external program like tr
, you can use bash expansion:
for f in *[A-Z]*
do
if [[ -f $f ]]; then
new_name=${f,,*}
mv "$f" "$new_name"
fi
done
Change filenames to lowercase in Ubuntu in all subdirectories
Here's one way using find
and tr
:
for i in $(find . -type f -name "*[A-Z]*"); do mv "$i" "$(echo $i | tr A-Z a-z)"; done
Edit; added: -name "*[A-Z]*"
This ensures that only files with capital letters are found. For example, if files with only lowercase letters are found and moved to the same file, mv
will display the are the same file
error.
How can i find and rename multiple files
Possible solution with Perl rename
:
find /mydir -depth -type f -exec rename -v 's/(.*\/)?([^.]*)/$1\U$2/' {} +
The commands in the question have several problems.
You seem to confuse the syntax of find
's -exec
action and xargs
.
find /mydir -depth -type f -exec rename -v 'substitution_command' {} \;
find /mydir -depth -type f| xargs -n 1 rename -v 'substitution_command'
The xargs
version has problems in case a file name contains a space.
If you replace \;
with +
, multiple file names are passed to one invocation of rename
.
The substitution command is only supported by the Perl version of the rename
command. You might have to install this version. See Get the Perl rename utility instead of the built-in rename
The substitution did not work in my test. I successfully used
rename -v 's/(.*\/)?([^.]*)/$1\U$2/' file ...
The first group (.*\/)?
optionally matches a sequence of characters with a trailing /
. This is used to copy the directory unchanged.
The second group ([^.]*)
matches a sequence of characters except .
.
This is the file name part before the first dot (if any) which will be converted to uppercase. In case the file name has more than one extension, all will remain unchanged, e.g.Path/To/Foo.Bar.Baz
-> Path/To/FOO.Bar.Baz
Related Topics
Setting Up Ftp on Amazon Cloud Server
How to Find the Last Field Using 'Cut'
Error When Using Git Credential Helper With Gnome-Keyring as Sudo
Automating Running Command on Linux from Windows Using Putty
Can Awk Patterns Match Multiple Lines
Why Is a Tilde in a Path Not Expanded in a Shell Script
Quickly Create a Large File on a Linux System
Command Not Found When Using Sudo
How to Copy Commits from One Git Repo to Another
How to Change 'Rpath' in an Already Compiled Binary
Difference Between Using 'Sh' and 'Source'
Find Multiple Files and Rename Them in Linux
Maximum Number of Processes in Linux
How to Configure Apache 2 to Run Perl Cgi Scripts