¿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.