I want to uppercase just the first character in my string with bash.
foo="bar";
//uppercase first character
echo $foo;
should print Bar.
I want to uppercase just the first character in my string with bash.
foo="bar";
//uppercase first character
echo $foo;
should print Bar.
One way with bash (version 4+):
foo=bar
echo "${foo^}"
prints:
Bar
"${foo,}". To lowercase all the letters, use "${foo,,}". To uppercase all the letters, use "${foo^^}".${foo~} and ${foo~~} have the same effect as ${foo^} and ${foo^^}. But I never saw that alternative mentioned anywhere.bad substitutionfoo="$(tr '[:lower:]' '[:upper:]' <<< ${foo:0:1})${foo:1}"
notQuiteCamel into NotQuiteCamel. Your variant has the side effect or forcing the remaining to lowercase - at the cost of doubling the number of sub shells and tr processes.bash.One way with sed:
echo "$(echo "$foo" | sed 's/.*/\u&/')"
Prints:
Bar
brew install coreutils gnu-sed and follow the instructions to use the commands without the prefix g. For what it's worth I've never wanted to run the OSX version of these commands since getting the GNU versions.sed 's/./\U&/ and it will work on POSIX sed.echo "bar" | sed 's/./\U&/' produces Ubar on mac. I think \U is not POSIX standard but a GNU extension.To capitalize first word only:
foo='one two three'
foo="${foo^}"
echo $foo
One two three
To capitalize every word in the variable:
foo="one two three"
foo=( $foo ) # without quotes
foo="${foo[@]^}"
echo $foo
One Two Three
(works in bash 4+)
foo='one two three'; foo=$(for i in $foo; do echo -n "${i^} "; done) Shorter resolution for every word. foo Now is "One Two Three"Using awk only
foo="uNcapItalizedstrIng"
echo $foo | awk '{print toupper(substr($0,0,1))tolower(substr($0,2))}'
Here is the "native" text tools way:
#!/bin/bash
string="abcd"
first=`echo $string|cut -c1|tr [a-z] [A-Z]`
second=`echo $string|cut -c2-`
echo $first$second
tr [:lower:] [:upper:] is a better choice if it needs to work in language/locales incorporating letters that aren't in the a-z or A-Z ranges.Translate the contents of file1 to upper-case. is tr "[:lower:]" "[:upper:]" < file1 and that (This should be preferred over the traditional UNIX idiom of “tr a-z A-Z”, since it works correctly in all locales.).just for fun here you are :
foo="bar";
echo $foo | awk '{$1=toupper(substr($1,0,1))substr($1,2)}1'
# or
echo ${foo^}
# or
echo $foo | head -c 1 | tr [a-z] [A-Z]; echo $foo | tail -c +2
# or
echo ${foo:1} | sed -e 's/^./\B&/'
awk solution works with any POSIX-compliant awk.)It can be done in pure bash with bash-3.2 as well:
# First, get the first character.
fl=${foo:0:1}
# Safety check: it must be a letter :).
if [[ ${fl} == [a-z] ]]; then
# Now, obtain its octal value using printf (builtin).
ord=$(printf '%o' "'${fl}")
# Fun fact: [a-z] maps onto 0141..0172. [A-Z] is 0101..0132.
# We can use decimal '- 40' to get the expected result!
ord=$(( ord - 40 ))
# Finally, map the new value back to a character.
fl=$(printf '%b' '\'${ord})
fi
echo "${fl}${foo:1}"
foo = $1 but I only get -bash: foo: command not found= in assignments. This is something that shellcheck.net will find for you programatically.= as an argument to a program (how is it supposed to know if someprogram = is running someprogram, or assigning to a variable named someprogram?)This works too...
FooBar=baz
echo ${FooBar^^${FooBar:0:1}}
=> Baz
FooBar=baz
echo ${FooBar^^${FooBar:1:1}}
=> bAz
FooBar=baz
echo ${FooBar^^${FooBar:2:2}}
=> baZ
And so on.
Sources:
Inroductions/Tutorials:
This one worked for me:
Searching for all *php file in the current directory , and replace the first character of each filename to capital letter:
e.g: test.php => Test.php
for f in *php ; do mv "$f" "$(\sed 's/.*/\u&/' <<< "$f")" ; done
This is POSIX sh-compatible as far as I know.
upper_first.sh:
#!/bin/sh
printf "$1" | cut -c1 -z | tr -d '\0' | tr [:lower:] [:upper:]
printf "$1" | cut -c2-
cut -c1 -z ends the first string with \0 instead of \n. It gets removed with tr -d '\0'. It also works to omit the -z and use tr -d '\n' instead, but this breaks if the first character of the string is a newline.
Usage:
$ upper_first.sh foo
Foo
$
In a function:
#!/bin/sh
function upper_first ()
{
printf "$1" | cut -c1 -z | tr -d '\0' | tr [:lower:] [:upper:]
printf "$1" | cut -c2-
}
old="foo"
new="$(upper_first "$old")"
echo "$new"
first-letter-to-lower () {
str=""
space=" "
for i in $@
do
if [ -z $(echo $i | grep "the\|of\|with" ) ]
then
str=$str"$(echo ${i:0:1} | tr '[A-Z]' '[a-z]')${i:1}$space"
else
str=$str${i}$space
fi
done
echo $str
}
first-letter-to-upper-xc () {
v-first-letter-to-upper | xclip -selection clipboard
}
first-letter-to-upper () {
str=""
space=" "
for i in $@
do
if [ -z $(echo $i | grep "the\|of\|with" ) ]
then
str=$str"$(echo ${i:0:1} | tr '[a-z]' '[A-Z]')${i:1}$space"
else
str=$str${i}$space
fi
done
echo $str
}
first-letter-to-lower-xc(){ v-first-letter-to-lower | xclip -selection clipboard }
Not exactly what asked but quite helpful
declare -u foo #When the variable is assigned a value, all lower-case characters are converted to upper-case.
foo=bar
echo $foo
BAR
And the opposite
declare -l foo #When the variable is assigned a value, all upper-case characters are converted to lower-case.
foo=BAR
echo $foo
bar
What if the first character is not a letter (but a tab, a space, and a escaped double quote)? We'd better test it until we find a letter! So:
S=' \"ó foo bar\"'
N=0
until [[ ${S:$N:1} =~ [[:alpha:]] ]]; do N=$[$N+1]; done
#F=`echo ${S:$N:1} | tr [:lower:] [:upper:]`
#F=`echo ${S:$N:1} | sed -E -e 's/./\u&/'` #other option
F=`echo ${S:$N:1}
F=`echo ${F} #pure Bash solution to "upper"
echo "$F"${S:(($N+1))} #without garbage
echo '='${S:0:(($N))}"$F"${S:(($N+1))}'=' #garbage preserved
Foo bar
= \"Foo bar=
$[...]). You're using lots of useless parentheses. You're assuming that the string consists of characters from the latin alphabet (how about accentuated letters, or letters in other alphabets?). You have a great deal of work to render this snippet usable! (and since you're using regex, you might as well use the regex to find the first letter, instead of a loop).tr: if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]].*) ]]; then out=${BASH_REMATCH[1]}${BASH_REMATCH[2]^}; else out=$S; fi; printf '%s\n' "$out"echo $foo is an example of a situation where the parser expects a list of words; so in your echo ${F}, the contents of F are string-split and glob-expanded. That's similarly true for the echo ${S:$N:1} example and all the rest. See BashPitfalls #14.