7

I'm trying to learn to rename files with the command line, and after browsing around a lot of pages I finally found a command that uppercases the first letter of a file, but the problem is that I want to understand the meaning of each command. The command is:

for i in *; do new=`echo "$i" | sed -e 's/^./\U&/'`; mv "$i" "$new";done

I understand the 'for' kinda... but not the 'echo' or '`' and especially the sed command. if someone has a little patience to explain the meaning of each thing that'd be awesome! Thanks!

5 Answers 5

17
for i in *; 
    do new=`echo "$i" | sed -e 's/^./\U&/'`;
    mv "$i" "$new";
done;

Would be the entire code broken down to make it easily viewable, I'll explain below.


First we have to make sure we process every file, the following line means: "Do the following as long as you can find files"

for i in *;

Then we have to load the current filname (which is stored in variable $i), replace the first letter by a capitalized version and store the new name (in variable $new).

The following command basically means: Make variable $new (do new=) Load $i and forward it ("$i" |) to a function that replaces the first letter by a capitalized one. (sed -e 's/^./\U&/';`)

The sed manual page can be found here. It's used to perform basic text transformations. What is basically does is use a regular expression (the 's/^./\U&/' part) (a way of detecting a certain pattern in a text) to detect first-characters that are uncapitalized and replace it with a capitalized version.

do new=echo "$i" | sed -e 's/^./\U&/';

After we've gotten the new name, it's time to rename the file with it's new capitalized name, the following command does that.

It says: move (same as rename) the old file foo.bar to the new Foo.bar.

mv "$i" "$new";

So we now have one file renamed and it's time to move to the next. The following concludes the for function, telling it it is now time to move on and process the next file.

done;
2
  • 4
    Nice explanation. It's worth noting that the \U in sed to uppercase the replacement is a GNU sed extension, and is likely not to work on UNIX systems where a different sed is used.
    – coneslayer
    Jun 10, 2010 at 18:00
  • 1
    this command appends a letter U infront of every file name. Which is undesired
    – angry kiwi
    Mar 22, 2013 at 5:00
5

Here are a couple of other techniques in case your sed doesn't support \U:

for i in *; do first=$(echo "${i:0:1}" | tr '[:lower:]' '[:upper:]'); new=$first${i:1}; mv "$i" "$new"; done

If you have Bash 4:

for i in *; do mv "$i" "${i^}"; done
4

Welcome to Bash, where just about everything is possible if not immediately obvious.

BloodPhilia explanation is very good for your specific request. If you are interested, here are some additional web resources to learn more:

Bash:

Sed (which is the 'S'tream 'ED'itor):

1
  • Well it does add to my answer and even refers to it ;) Some people make a habit out of copying it without adding anything... Yours actually adds something to mine... I like that =)
    – Pylsa
    Jun 11, 2010 at 15:56
1

To capitalize each first character in filename with BASH you can use a following construct: file_words=( $file ) echo "${file_words[@]^}"

It's much clearer than using sed and you only use BASH, so it's faster.

0

And if you have zsh :

for i in *; do mv $i ${(C)i}; done
4
  • That capitalization flag will capitalize the first character of all maximal alphanumeric subsequences, not just the first character (foo=bar.baz && echo ${(C)foo} gives Bar.Baz). Try ${(C)i[1]}${i[2,-1]}. Jun 11, 2010 at 3:14
  • Too bad, that's less elegant.... Thanks though.
    – Henno
    Jun 11, 2010 at 9:52
  • 1
    Nice regex, if you have zmv it's easier: zmv '(*)' '${(C)1[1]}${1[2,-1]}'
    – Andy D
    Jun 2, 2016 at 20:22
  • @AndyD This should be its own answer. This is exactly what I was looking for.
    – bdetweiler
    Dec 11, 2020 at 15:38

You must log in to answer this question.

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