Reputation: 8086
For example: var=dog
and echo $var
output is dog. Capitalize $var
expected output Dog.
Tried multiple ways but just not getting the expected output. Some attempts:
echo $var | sed "s/[a-z]\&[:upper:]//" #dog
echo $var | sed "s/([a-z])/[:upper:]/" #dog
Upvotes: 5
Views: 3198
Reputation: 438073
tl;dr:
macOS, with Unicode support, OR cross-platform, but ASCII-only, and for background information:
tr
solution below.GNU utilities, with Unicode support (Linux: preinstalled; macOS: installable via Homebrew):
sed 's/^./\u&/' <<<'dog' # -> 'Dog'
brew install gnu-sed
, use gsed
instead of sed
awk
alternative: see dev-null's answer
brew install gawk
, use gawk
instead of awk
.Cross-platform, with Unicode support:
perl
: see dawg's answerpython
: see idjaw's answerBash 4+, with Unicode support, which on macOS you can also install with Homebrew:
echo "${var^}"
Try
var='dog'
echo "$(tr '[:lower:]' '[:upper:]' <<<"${var:0:1}")${var:1}" # -> 'Dog'
tr '[:lower:]' '[:upper:]' <<<"${var:0:1}"
extracts the 1st char from $var
(${var:0:1}
) and uses tr
to translate it to uppercase.
${var:1}
returns everything from the 2nd char in $var
's value.
Note that this solution is Unicode-aware[1], unlike the macOS awk
and Python 2.x solutions Update: @idjaw fixed the Python 2.x solution with .decode('utf-8')
, and presumably also slightly faster than them (tr
is lighter-weight than awk
and python
).
[1] This applies to the BSD tr
version that comes with macOS. GNU tr
, by contrast, does not handle non-ASCII characters correctly - as John1024 notes, according to Wikipedia, "Most versions of tr, including GNU tr and classic Unix tr, operate on single-byte characters and are not Unicode compliant.".
As for your attempt at a sed
solution:
Using macOS's (BSD) sed
, I'm not aware of any substring-manipulation features.
If you had GNU sed
- which you could install via Homebrew - you could use the following:
sed 's/^./\u&/' <<<'dog' # -> 'Dog'
\u
tells GNU Sed to capitalize the following letter. Sadly, you can't do that with macOS's Sed.
[:upper:]
only ever works as a matching character class, it never performs transformation, which is why your command didn't work.
The only exception is tr
, where you can pair an [:upper:]
with a [:lower:]
to effect transformation, as in my solution above.
Sneak preview of a Bash 4+ solution:
var='dog'; echo "${var^}"
Upvotes: 11
Reputation: 26586
You can use Python if that's an option:
After input from different people (thanks all), this seems to be a good working solution that is in line with OP requests for only the first letter as proposed by @PM2Ring:
Best proposed solution for first character only
bash-3.2$ var="it's an öyster's life"
bash-3.2$ python -c "import sys;print sys.argv[1].decode('utf8').capitalize()" "$var"
It's an öyster's life
Following solutions attempt to capitalize all first characters of words in a string:
The following solution has some drawbacks:
bash-3.2$ python -c "print raw_input().decode('utf-8').title()" <<<"it's an öyster's life"
It'S An Öyster'S Life
Simple solution using a variable:
bash-3.2$ var='dog is dog'
bash-3.2$ python -c "print raw_input().decode('utf-8').title()" <<<"$var"
Dog Is Dog
As can be seen from the comments in this answer (thanks for the input all), it is important to note the limitations of using this, especially using OSX native Python language 2.7.
Example 1: (Thanks @john1024 & @dev-null)
Quote issues.
small modification with quotes required to handle the below string sample
var="it's a dog's life"
bash-3.2$ python -c "print '$var'.title()"
It'S A Dog'S Life
Additional example that does not work with my solution: var="hello ''' world"
Example 2: (Thanks @mklement0)
Unicode issues
bash-3.2$ var='öyster'
bash-3.2$ python -c "print '$var'.title()"
öYster
Notice that it capitalized the second letter, which is the first ascii character that the title method will capitalize per how it is expected in Python2.
The following modification to the solution can be made to help with unicode characters:
bash-3.2$ var='öyster'
python -c "print '$var'.decode('utf-8').title()"
Öyster
Finally, when putting the solutions together from the discussion below, this is how it was put together to finally have:
python -c "print raw_input().decode('utf-8').title()" <<<"it's an öyster's life"
Upvotes: 3
Reputation: 103874
If you want to be unicode aware, consider using perl:
$ perl -lne 'use open qw(:std :utf8); print ucfirst' <<< 'dog'
Dog
$ perl -lne 'use open qw(:std :utf8); print ucfirst' <<< 'élan'
Élan
As pointed out in comments:
$ perl -C -lne 'print ucfirst' <<< 'élan'
Élan
Upvotes: 3
Reputation: 47099
var="hello world"
echo "$var" | awk '{print toupper(substr($0, 1, 1)) substr($0, 2)}' # Hello world
and if you want to Capitalize Each Word:
var="hello world"
echo "$var" | awk 'BEGIN{RS = " "};{printf("%s ", toupper(substr($0, 1, 1)) substr($0, 2))}' # Hello World
Upvotes: 4