19

Is there a way to rename all files in a directory to lowercase|uppercase?

I am looking for a oneliner command.

I loved TotalCommander's Alt + F7, now I need that functionality in the Terminal.

4 Answers 4

20

For each file a_file in current directory rename a_file to lower case.

for a_file in *;do mv -v "$a_file" `echo "$a_file" | tr [:upper:] [:lower:]` ;done;

For upper case reverse the arguments to [:lower:] [:upper:]

tr command reference link

Update

For even more control * can be replaced with ls.

For example in a directory containing 1.txt, 2.txt, 3.txt, 1.jpg, 2.jpg and 3.jpg in order to filter only *.jpg files, ls can be used:

for a_file in $(ls *.jpg);do mv -v $a_file `echo $a_file | tr [:upper:] [:lower:]` ;done;

The above code will assign to a_file variable all files with .jpg extension.

Update added -v option to mv command as per sds suggested.

4
  • 4
    you might want to pass "-v" to mv so that you see what is being done; you might not want to pass "-f" because this may clobber existing files
    – sds
    Apr 18, 2013 at 14:33
  • This does not work for files with spaces in their name. Feb 17, 2016 at 5:03
  • You can use quotes around the filename.
    – Stef K
    Feb 17, 2016 at 6:26
  • 3
    Sorry, but the part about ls *jpg is a bad idea. mywiki.wooledge.org/ParsingLs You can achive the same result with *jpg along where you had * in the first place.
    – tink
    Mar 17, 2016 at 23:43
17

There's a more elegant and general utility called prename.

Written by Larry Wall, it comes with perl so it is most likely already available on your system as /usr/bin/prename (if you have setup alternatives is may also be available as /usr/bin/rename symlinked via /etc/alternatives to prename)

Using it you can rename multiple files in one command by providing any perl expression (including but not limited to substitution s/// or char transliteration tr///):

Examples:

# Lowercase all *.JPG filenames:
prename tr/A-Z/a-z/ *.JPG

# Change any 'No' in a filename to a 'Yes':
prename s/No/Yes/g *No*

# increment first sequence of digits in a filename by 3:
prename 's/([0-9]+)/$1+3/e' *[0-9]*

# If a file contains 'aaa', append '.bak' to its name
prename 'if (/aaa/) {$_ .= ".bak"}'  *

And so on.

Another nice thing about prename is that it protects you, in the case of renaming a file to an existing file name.

man prename for more details.

1

Using find

find . -name * -type f -exec rename 'y/A-Z/a-z/' '{}' \;

For find

  • Of course after -name put your pattern.
  • -maxdepth 0: Only current directory.

For rename

  • -n, -nono: No action: print names of files to be renamed, but don't rename.
  • y/source/dest/: Transliterate the characters in the pattern space which appear in source to the corresponding character in dest.
0

Using mmv to convert matched string to uppercase:

$ mmv -r '*' '#u1'

Its important to quote the pattern otherwise it will expand the wildcard instead.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .