¿Cómo poner en mayúscula el argumento de la línea de comando?


125

Busqué SO y descubrí que, en mayúscula, una cadena siguiente funcionaría

str="Some string"
echo ${str^^}

Pero intenté hacer algo similar en un argumento de línea de comandos, que me dio el siguiente error

Intentó

#!/bin/bash
             ## Output
echo ${1^^}  ## line 3: ${1^^}: bad substitution
echo {$1^^}  ## No error, but output was still smaller case i.e. no effect

¿Cómo podemos hacer esto?


8
A mí me funciona bien. Publique su secuencia de comandos completa, el error probablemente esté en otra parte. ¿Está apuntando tu shebang bash?
manatwork

Respuestas:


151

La sintaxis str^^que está intentando está disponible en Bash 4.0 y superior. Quizás la tuya sea una versión anterior (o ejecutaste el script shexplícitamente):

Prueba esto:

str="Some string"
printf '%s\n' "$str" | awk '{ print toupper($0) }'

1
Por las palabras de mtk, entendí que la modificación de casos realmente funciona para él con variables.
manatwork

1
@manatwork Eso no está claramente establecido en la pregunta inicial. El mensaje de error de sustitución incorrecta es el mismo que obtendría con versiones anteriores de bash.
Bernhard

44
Estás en lo correcto. Revisé la versión, es 3.2.25. Su solución funciona y también lo intenté tr '[a-z]' [[A-Z]'.
mtk

20
@mtk Eso debería ser tr '[a-z]' '[A-Z]'.
l0b0

2
Estoy en ejecución GNU bash, version 4.3.42(1)-release (x86_64-apple-darwin14.5.0)y obtengo el mismo error que OP, así que no creo que esté disponible en ninguna bashversión 4.0 o superior como usted dice.
Heath Borders

79
echo "lowercase" | tr a-z A-Z

Salida:

LOWERCASE

1
Creo POSIX no requiere que el /que en tr /a-z/ /A-Z/antes de mi edición: esto sólo funciona porque se reemplaza /por el /, pero es inútil: pubs.opengroup.org/onlinepubs/9699919799/utilities/tr.html También existe la más oscura y menos útil tr '[:lower:]' '[:upper:]'.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Correcto. tr es muy diferente, pero funciona.
Doug

las diéresis no funcionan con esto.
Evgeny

22

Tenga cuidado con tr a menos que AZ sea todo lo que use. Para otros entornos locales, incluso '[: lower:]' '[: upper:]' falla, solo funciona el toupper y bash (v4 +) de awk

$ str="abcåäö"
$ echo "$str"|tr '/a-z/' '/A-Z/'
ABCåäö
$ echo "$str"|LC_ALL=sv_SE tr '[:lower:]' '[:upper:]'
ABCåäö
$ echo "$str"|awk '{print toupper($0)}'
ABCÅÄÖ
$ echo ${str^^} # Bash 4.0 and later
ABCÅÄÖ
$ STR="ABCÅÄÖ"
$ echo ${STR,,}
abcåäö

1
FWIW, tr '[:lower:]' '[:upper:]'está trabajando ahora para su ejemplo en OS X al menos (también con LC_ALL=sv_SE)
Ethan

1

Alternativamente, puede cambiar a ksh o zsh que han tenido soporte para la conversión de mayúsculas y minúsculas durante décadas (mucho antes bashde que se ${var^^}agregara en 4.0), aunque con una sintaxis diferente:

#! /bin/ksh -
typeset -u upper="$1"
printf '%s\n' "$upper"

(también funciona con zsh; tenga en cuenta que en pdksh / mksh, eso solo funciona para letras ASCII).

Con zsh, también puede usar el Uindicador de expansión de parámetros:

#! /bin/zsh -
printf '%s\n' "${(U)1}"

POSIBLEMENTE, puede usar:

awk 'BEGIN{print toupper(ARGV[1])}' "$1"

También hay:

printf '%s\n' "$1" | tr '[:lower:]' '[:upper:]'

Pero en algunas implementaciones, incluida GNU tr, eso solo funciona para caracteres de un solo byte (por lo tanto, en configuraciones regionales UTF-8, solo en letras ASCII).


0

Si alguien sigue recibiendo errores al intentarlo ${str^^}, puede intentarlo python -co perles probable porque la versión bash es inferior a 4.

Pero, hasta ahora, bash 4 o superior está funcionando rápidamente con la solución existente.

L2U="I will be upper"

Usando python -cen bash

python -c "print('$L2U'.upper())"
I WILL BE UPPER

Del mismo modo, también se puede utilizar para capitalizar con:

service="bootup.sh on home"
python -c "print('$service'.capitalize())"
Bootup.sh on home

Utilizando perl

echo $L2U | perl -ne 'print "\U$_"'
I WILL BE UPPER
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.