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.

Pablo Bianchi
  • 15,657

4 Answers4

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.

Stef K
  • 4,836
  • 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 '13 at 14:33
  • This does not work for files with spaces in their name. – Tianxiang Xiong Feb 17 '16 at 05:03
  • You can use quotes around the filename. – Stef K Feb 17 '16 at 06:26
  • 3
    Sorry, but the part about ls jpg is a bad* idea. http://mywiki.wooledge.org/ParsingLs You can achive the same result with jpg along where you had in the first place. – tink Mar 17 '16 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.

arielf
  • 2,823
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.
Pablo Bianchi
  • 15,657
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.