A pesar de ser más complejo que la respuesta mejor calificada, esta realmente hace exactamente eso: 'primer carácter en mayúscula en una variable'. La respuesta mejor calificada no tiene ese resultado. ¿Parece que las respuestas simples se votan de mejor manera que las correctas?
Krzysztof Jabłoński
15
@ KrzysztofJabłoński: En realidad, la "respuesta mejor calificada" a continuación producirá los mismos resultados que esta respuesta en Bash 4. Esta respuesta tiene la sobrecarga de llamar a una subshell (otra shell), la sobrecarga de llamar a la utilidad 'tr' (otro proceso , no Bash), la sobrecarga de usar here-doc / string (creación de archivo temporal) y usa dos sustituciones en comparación con la respuesta mejor calificada. Si absolutamente debe escribir código heredado, considere usar una función en lugar de una subshell.
Steve
2
Esta respuesta asume que la entrada es todo en minúsculas. Esta variante no tiene supuestos: $ (tr '[: lower:]' '[: upper:]' <<< $ {foo: 0: 1}) $ (tr '[: upper:]' '[: lower: ] '<<< $ {foo: 1})
Itai Hanski
55
@ItaiHanski El OP no especificó qué debería pasar con los personajes restantes, solo el primero. Se supone que querían cambiar notQuiteCamela 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.
Jesse Chisholm
3
@DanieleOrlando, cierto, pero esta pregunta no tiene otras etiquetas que no sean bash.
@CMCDragonkai: para poner en minúscula la primera letra, use "${foo,}". Para minúsculas todas las letras, use "${foo,,}". Para poner en mayúscula todas las letras, use "${foo^^}".
Steve
1
Accidentalmente noté eso ${foo~}y ${foo~~}tengo el mismo efecto que ${foo^}y ${foo^^}. Pero nunca vi esa alternativa mencionada en ninguna parte.
mivk
55
Esto no parece funcionar en Mac. obteniendo el siguiente error:bad substitution
Toland Hon
1
@TolandHon: Como probablemente ya haya trabajado, necesitará actualizar a la versión 4.x, o probar otra solución si esa máquina no puede actualizarse por alguna razón.
no funciona en MacOS10 Lion sed, suspiro, el \ u se expande hacia ti en lugar de ser un operador.
vwvan
2
@vwvan brew install coreutils gnu-sedy 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.
Dean el
@vwvan: Sí, lo siento, necesitarás GNU seden este caso
Steve
2
@Dean: FWIW, nunca quise ejecutar OSX :-)
Steve
55
Simplemente cámbielo a sed 's/./\U&/y funcionará en POSIX sed.
finalmente algo que funciona con una variable y en Mac! ¡Gracias!
OZZIE
44
@DanieleOrlando, no es tan portátil como cabría esperar. tr [:lower:] [:upper:]es una mejor opción si necesita trabajar en idiomas / idiomas incorporando letras que no están en los rangos a-zo A-Z.
# 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}"
¿Cómo definir foo? Lo intenté foo = $1pero solo consigo-bash: foo: command not found
OZZIE
1
@OZZIE, no hay espacios alrededor de las =asignaciones. Esto es algo que shellcheck.net encontrará para usted programáticamente.
Charles Duffy
Siempre olvido eso de los scripts de shell ... solo lenguaje donde un espacio (antes / después) importa ... suspiro (python es al menos 4 si no recuerdo
mal
@OZZIE, tiene que importar, porque si no importara, no podría pasar =como argumento a un programa (¿cómo se supone que debe saber si se someprogram =está ejecutando someprogramo asignando a una variable llamada someprogram?)
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"
vr286
¿Cómo puedo poner en mayúscula las primeras 3 o 4 letras en mayúscula? ¿Como pqrs-123-v1 a PQRS-123-v1 ? O puede decir, todas las letras antes del primer guión ...
Vicky Dev hace
2
Solución alternativa y limpia para Linux y OSX, también se puede usar con variables bash
¿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:
¡Por favor escriba un código más limpio! te faltan citas por todas partes. Estás utilizando una sintaxis obsoleta (backticks); estás usando una sintaxis anticuada ( $[...]). 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).
gniourf_gniourf
66
Creo que estas equivocado. Es el comentario obligatorio que acompaña al voto negativo, explicando todos los patrones y conceptos erróneos incorrectos de la respuesta. Por favor, aprenda de sus errores (y antes de eso, trate de entenderlos) en lugar de ser terco. Ser un buen compañero también es incompatible con la difusión de malas prácticas.
gniourf_gniourf
1
O, si usa Bash ≥4, no necesita tr:if [[ $S =~ ^([^[:alpha:]]*)([[:alpha:]].*) ]]; then out=${BASH_REMATCH[1]}${BASH_REMATCH[2]^}; else out=$S; fi; printf '%s\n' "$out"
gniourf_gniourf
55
Este código todavía está muy roto. Todavía usa backticks en lugar de la sintaxis de sustitución moderna; todavía tiene citas inigualables; todavía le faltan citas en lugares donde sí importan ; Etc. Intente poner algunos caracteres de globo en espacios en blanco en sus datos de prueba, si no cree que esas comillas faltantes marcan la diferencia, y solucione los problemas que shellcheck.net encuentra hasta que este código salga limpio.
Charles Duffy
2
En cuanto al idioma que citó en unix.stackexchange.com/questions/68694/… , lo que echa de menos es que echo $fooes 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 Fse 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 .
Respuestas:
fuente
notQuiteCamel
aNotQuiteCamel
. 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+):
huellas dactilares:
fuente
"${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
:Huellas dactilares:
fuente
brew install coreutils gnu-sed
y siga las instrucciones para usar los comandos sin el prefijog
. Por lo que vale, nunca quise ejecutar la versión OSX de estos comandos desde que obtuve las versiones GNU.sed
en este casosed 's/./\U&/
y funcionará en POSIX sed.fuente
Aquí está la forma de herramientas de texto "nativo":
fuente
tr [:lower:] [:upper:]
es una mejor opción si necesita trabajar en idiomas / idiomas incorporando letras que no están en los rangosa-z
oA-Z
.Usar solo awk
fuente
También se puede hacer en bash puro con bash-3.2:
fuente
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 sesomeprogram =
está ejecutandosomeprogram
o asignando a una variable llamadasomeprogram
?)Esto también funciona ...
Y así.
Fuentes:
Inroducciones / Tutoriales:
fuente
Para capitalizar solo la primera palabra:
Para capitalizar cada palabra en la variable:
(funciona en bash 4+)
fuente
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
devuelve Abc
fuente
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
fuente
solo por diversión aquí estás:
fuente
No es exactamente lo que pedí pero es bastante útil
Y lo contrario
fuente
first-letter-to-lower-xc () {v-first-letter-to-lower | xclip -selection portapapeles}
fuente
¿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:
fuente
$[...]
). 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 tuecho ${F}
, el contenido deF
se divide en cadenas y se expande globalmente. Eso es igualmente cierto para elecho ${S:$N:1}
ejemplo y todo lo demás. Ver BashPitfalls # 14 .