Quiero poner en mayúscula solo el primer carácter de mi cadena con bash.
foo="bar";
//uppercase first character
echo $foo;
debe imprimir "Bar";
Quiero poner en mayúscula solo el primer carácter de mi cadena con bash.
foo="bar";
//uppercase first character
echo $foo;
debe imprimir "Bar";
Respuestas:
foo="$(tr '[:lower:]' '[:upper:]' <<< ${foo:0:1})${foo:1}"
notQuiteCamel
a NotQuiteCamel
. Su variante tiene el efecto secundario u obliga al resto a minúsculas, a costa de duplicar el número de subcapas y procesos tr.
bash
.
Una forma con bash (versión 4+):
foo=bar
echo "${foo^}"
huellas dactilares:
Bar
"${foo,}"
. Para minúsculas todas las letras, use "${foo,,}"
. Para poner en mayúscula todas las letras, use "${foo^^}"
.
${foo~}
y ${foo~~}
tengo el mismo efecto que ${foo^}
y ${foo^^}
. Pero nunca vi esa alternativa mencionada en ninguna parte.
bad substitution
Unidireccional con sed
:
echo "$(echo "$foo" | sed 's/.*/\u&/')"
Huellas dactilares:
Bar
brew install coreutils gnu-sed
y siga las instrucciones para usar los comandos sin el prefijo g
. Por lo que vale, nunca quise ejecutar la versión OSX de estos comandos desde que obtuve las versiones GNU.
sed
en este caso
sed 's/./\U&/
y funcionará en POSIX sed.
$ foo="bar";
$ foo=`echo ${foo:0:1} | tr '[a-z]' '[A-Z]'`${foo:1}
$ echo $foo
Bar
Aquí está la forma de herramientas de texto "nativo":
#!/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:]
es una mejor opción si necesita trabajar en idiomas / idiomas incorporando letras que no están en los rangos a-z
o A-Z
.
Usar solo awk
foo="uNcapItalizedstrIng"
echo $foo | awk '{print toupper(substr($0,0,1))tolower(substr($0,2))}'
También se puede hacer en bash puro con 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
pero solo consigo-bash: foo: command not found
=
asignaciones. Esto es algo que shellcheck.net encontrará para usted programáticamente.
=
como argumento a un programa (¿cómo se supone que debe saber si se someprogram =
está ejecutando someprogram
o asignando a una variable llamada someprogram
?)
Esto también funciona ...
FooBar=baz
echo ${FooBar^^${FooBar:0:1}}
=> Baz
FooBar=baz
echo ${FooBar^^${FooBar:1:1}}
=> bAz
FooBar=baz
echo ${FooBar^^${FooBar:2:2}}
=> baZ
Y así.
Fuentes:
Inroducciones / Tutoriales:
Para capitalizar solo la primera palabra:
foo='one two three'
foo="${foo^}"
echo $foo
O ne dos tres
Para capitalizar cada palabra en la variable:
foo="one two three"
foo=( $foo ) # without quotes
foo="${foo[@]^}"
echo $foo
O ne T wo T tres
(funciona en bash 4+)
foo='one two three'; foo=$(for i in $foo; do echo -n "${i^} "; done)
Resolución más corta para cada palabra. foo Ahora es "One Two Three"
Solución alternativa y limpia para Linux y OSX, también se puede usar con variables bash
python -c "print(\"abc\".capitalize())"
devuelve Abc
Este me funcionó:
Buscar todos los archivos * php en el directorio actual y reemplazar el primer carácter de cada nombre de archivo con mayúscula:
Por ejemplo: test.php => Test.php
for f in *php ; do mv "$f" "$(\sed 's/.*/\u&/' <<< "$f")" ; done
solo por diversión aquí estás:
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&/'
No es exactamente lo que pedí pero es 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
Y lo contrario
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
}
first-letter-to-lower-xc () {v-first-letter-to-lower | xclip -selection portapapeles}
¿Qué sucede si el primer carácter no es una letra (sino una tabulación, un espacio y una comilla doble escapada)? Será mejor que prueba que hasta que encontramos una carta! Entonces:
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=
$[...]
). Estás usando muchos paréntesis inútiles. Estás asumiendo que la cadena consiste en caracteres del alfabeto latino (¿qué tal letras acentuadas o letras en otros alfabetos?). ¡Tienes mucho trabajo para hacer que este fragmento sea utilizable! (y dado que está utilizando expresiones regulares, también podría usar la expresión regular para encontrar la primera letra, en lugar de un bucle).
tr
:if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]].*) ]]; then out=${BASH_REMATCH[1]}${BASH_REMATCH[2]^}; else out=$S; fi; printf '%s\n' "$out"
echo $foo
es un ejemplo de una situación en la que el analizador espera una lista de palabras ; así que en tu echo ${F}
, el contenido de F
se divide en cadenas y se expande globalmente. Eso es igualmente cierto para el echo ${S:$N:1}
ejemplo y todo lo demás. Ver BashPitfalls # 14 .