Reputation: 41
I have a directory called "Theme_1" and I want to capitalize all the filenames starting with "theme". The first letter of every file name is lowercase and I want it to be upcase.
I've tried this but all the letters in the filename are upcase, which is not what I want.
for f in * ; do mv -- "$f" "$(tr [:lower:] [:upper:] <<< "$f")" ; done
I also tried this, but it doesn't work:
mv theme*.jpg Theme*.jpg
Upvotes: 2
Views: 2398
Reputation: 1668
I couldn't get what I wanted in Bash. So I spent 2 minutes and got this working in PHP. This is for future googlers who are looking for a solution and happen to have PHP on their system.
<?php
foreach(glob(__DIR__.'/*') as $filename) {
if($filename === '.' || $filename === '..') { continue; }
// To only capitalize the first letter of the file
$new_filename = ucfirst(basename($filename));
// To capitalize each word in the filename
//$new_filename = ucwords(basename($filename));
echo __DIR__.'/'.$new_filename."\n";
rename($filename, __DIR__.'/'.$new_filename);
}
Upvotes: 0
Reputation: 77107
In Bash 4 you can use parameter expansion directly to capitalize every letter in a word (^^
) or just the first letter (^
).
for f in *; do
mv -- "$f" "${f^}"
done
You can use patterns to form more sophisticated case modifications.
But for your specific question, aren't you working too hard? Just replace the word "theme" with the word "Theme" when it occurs at the beginning of filenames.
for f in theme*; do
mv "$f" "Theme${f#theme}"
done
Upvotes: 5
Reputation: 80931
Your first attempt was close but tr
operates on every character in its input.
You either need to use something like sed
that can operate on a single character or limit tr
to only seeing the first character.
for f in * ; do
mv -- "$f" "$(tr [:lower:] [:upper:] <<< "${f:0:1}")${f:1}"
done
That uses Shell Parameter Expansion to only give tr
the first character of the filename and then expand the rest of the filename after that.
Upvotes: 2