Quero colocar em maiúscula apenas o primeiro caractere na minha string com bash.
foo="bar";
//uppercase first character
echo $foo;
deve imprimir "Bar";
Quero colocar em maiúscula apenas o primeiro caractere na minha string com bash.
foo="bar";
//uppercase first character
echo $foo;
deve imprimir "Bar";
Respostas:
foo="$(tr '[:lower:]' '[:upper:]' <<< ${foo:0:1})${foo:1}"
notQuiteCamel
em NotQuiteCamel
. Sua variante tem o efeito colateral ou força o restante a minúsculo - ao custo de dobrar o número de subcascas e processos tr.
bash
.
Uma maneira com o bash (versão 4+):
foo=bar
echo "${foo^}"
impressões:
Bar
"${foo,}"
. Para minúsculas todas as letras, use "${foo,,}"
. Para colocar todas as letras em maiúsculas, use "${foo^^}"
.
${foo~}
e ${foo~~}
tem o mesmo efeito que ${foo^}
e ${foo^^}
. Mas nunca vi essa alternativa mencionada em nenhum lugar.
bad substitution
Uma maneira com sed
:
echo "$(echo "$foo" | sed 's/.*/\u&/')"
Impressões:
Bar
brew install coreutils gnu-sed
e siga as instruções para usar os comandos sem o prefixo g
. Pelo que vale a pena, eu nunca quis executar a versão OSX desses comandos desde a obtenção das versões GNU.
sed
neste caso
sed 's/./\U&/
e ele funcionará no POSIX sed.
$ foo="bar";
$ foo=`echo ${foo:0:1} | tr '[a-z]' '[A-Z]'`${foo:1}
$ echo $foo
Bar
Aqui está a maneira "nativa" das ferramentas de texto:
#!/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:]
é uma escolha melhor se precisar trabalhar em idiomas / localidades que incorporem letras que não estão nos intervalos a-z
ou A-Z
.
Usando apenas awk
foo="uNcapItalizedstrIng"
echo $foo | awk '{print toupper(substr($0,0,1))tolower(substr($0,2))}'
Isso também pode ser feito no bash puro com o bash-3.2:
# 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
mas só consigo-bash: foo: command not found
=
tarefas. Isso é algo que o shellcheck.net encontrará para você programaticamente.
=
como um argumento para um programa (como é suposto saber se someprogram =
está em execução someprogram
, ou atribuir a uma variável chamada someprogram
?)
Isso funciona também ...
FooBar=baz
echo ${FooBar^^${FooBar:0:1}}
=> Baz
FooBar=baz
echo ${FooBar^^${FooBar:1:1}}
=> bAz
FooBar=baz
echo ${FooBar^^${FooBar:2:2}}
=> baZ
E assim por diante.
Fontes:
Introduções / Tutoriais:
Para colocar em maiúscula apenas a primeira palavra:
foo='one two three'
foo="${foo^}"
echo $foo
O ne dois três
Para colocar em maiúscula todas as palavras na variável:
foo="one two three"
foo=( $foo ) # without quotes
foo="${foo[@]^}"
echo $foo
O ne t wo t rês
(funciona no bash 4+)
foo='one two three'; foo=$(for i in $foo; do echo -n "${i^} "; done)
Resolução mais curta para cada palavra. foo Agora é "um dois três"
Solução alternativa e limpa para Linux e OSX, também pode ser usada com variáveis bash
python -c "print(\"abc\".capitalize())"
retorna Abc
Este funcionou para mim:
Procurando por todos os arquivos * php no diretório atual e substitua o primeiro caractere de cada nome de arquivo por letra maiúscula:
por exemplo: test.php => Test.php
for f in *php ; do mv "$f" "$(\sed 's/.*/\u&/' <<< "$f")" ; done
Não é exatamente o que pediu, mas é bastante útil
declare -u foo #When the variable is assigned a value, all lower-case characters are converted to upper-case.
foo=bar
echo $foo
BAR
E o oposto
declare -l foo #When the variable is assigned a value, all upper-case characters are converted to lower-case.
foo=BAR
echo $foo
bar
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
}
primeira letra para abaixar xc () {v-primeira letra para abaixar | xclip -selection clipboard}
E se o primeiro caractere não for uma letra (mas uma tabulação, espaço e aspas duplas)? É melhor testá- lo até encontrarmos uma carta! Assim:
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=
$[...]
). Você está usando muitos parênteses inúteis. Você está assumindo que a sequência consiste em caracteres do alfabeto latino (que tal letras acentuadas ou em outros alfabetos?). Você tem muito trabalho para tornar esse trecho utilizável! (e como você está usando regex, você pode usá-lo para encontrar a primeira letra, em vez de um loop).
tr
:if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]].*) ]]; then out=${BASH_REMATCH[1]}${BASH_REMATCH[2]^}; else out=$S; fi; printf '%s\n' "$out"
echo $foo
é um exemplo de uma situação em que o analisador espera uma lista de palavras ; Assim, no seu echo ${F}
, o conteúdo de F
é dividido por cadeias e expandido por glob. O mesmo se aplica ao echo ${S:$N:1}
exemplo e a todo o resto. Veja BashPitfalls # 14 .