Como colocar em maiúsculas o argumento da linha de comandos?

125

Eu procurei no SO e descobri que, para maiúsculas, uma sequência a seguir funcionaria

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

Mas tentei fazer algo semelhante em um argumento de linha de comando, o que me deu o seguinte erro

Tentou

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

Como poderíamos fazer isso?

mtk
fonte
8
Ele funciona para mim muito bem. Poste seu script inteiro, o erro provavelmente está em outro lugar. Seu shebang está apontando bash?
manatwork
possível mesmo que: stackoverflow.com/questions/2264428/…
Ciro Santilli escreveu:

Respostas:

151

A sintaxe str^^que você está tentando está disponível no Bash 4.0 e acima. Talvez a sua seja uma versão mais antiga (ou você executou o script shexplicitamente):

Tente o seguinte:

str="Some string"
printf '%s\n' "$str" | awk '{ print toupper($0) }'
Guru
fonte
1
Pelas palavras de mtk, entendi que a modificação de casos realmente funciona para ele com variáveis.
manatwork
1
@manatwork Isso não está claramente indicado na pergunta inicial. A mensagem de erro de substituição incorreta é a mesma da versão anterior do bash.
10242 Bernhard
4
Você está certo. Eu verifiquei a versão, sua 3.2.25. Sua solução funciona e também tentei tr '[a-z]' [[A-Z]'.
mtk
20
@mtk Isso deve ser tr '[a-z]' '[A-Z]'.
L0b0 17/10/12
2
Estou em execução GNU bash, version 4.3.42(1)-release (x86_64-apple-darwin14.5.0)e recebo o mesmo erro do OP, portanto, não acho que isso esteja disponível em qualquer bashversão 4.0 ou superior, como você diz.
Heath Borders
79
echo "lowercase" | tr a-z A-Z

Resultado:

LOWERCASE
Johner Ramirez
fonte
1
Eu acho que não POSIX não exigem a /como tr /a-z/ /A-Z/antes de meu edit: isso só funciona porque substitui /por /mas é inútil: pubs.opengroup.org/onlinepubs/9699919799/utilities/tr.html Existe também o mais obscuro e menos útil tr '[:lower:]' '[:upper:]'.
Ciro Santilli #
Corrigir. tr é muito diferente, mas funciona.
Doug
os trema não estão trabalhando com isso.
Evgeny
22

Cuidado com tr, a menos que AZ seja tudo o que você usa. Para outros locais, mesmo '[: lower:]' '[: upper:]' falha, apenas o toupper e o bash do awk funcionam (v4 +)

$ 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åäö
lpaseen
fonte
1
FWIW, tr '[:lower:]' '[:upper:]'está trabalhando agora para o seu exemplo no OS X, pelo menos, (também com LC_ALL=sv_SE)
Ethan
1

Alternativamente, você pode mudar para ksh ou zsh que tiveram suporte de conversão caso por décadas (muito antes bashde ${var^^}adicionadas na versão 4.0), embora com uma sintaxe diferente:

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

(também funciona com zsh; observe que em pdksh / mksh, isso funciona apenas para letras ASCII).

Com zsh, você também pode usar o Usinalizador de expansão de parâmetro:

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

POSIXAMENTE, você pode usar:

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

Há também:

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

Porém, em algumas implementações, incluindo GNU tr, isso funciona apenas para caracteres de byte único (em locais UTF-8, apenas em letras ASCII).

Stéphane Chazelas
fonte
0

Se alguém ainda estiver recebendo erros ao tentar ${str^^}, tente python -cou perlé provável que a versão do bash seja menor que 4.

Até agora, o bash 4 ou mais está funcionando rapidamente com a solução existente.

L2U="I will be upper"

Usando python -cno bash

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

Da mesma forma, também pode ser usado para capitalizar com:

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

Usando perl

echo $L2U | perl -ne 'print "\U$_"'
I WILL BE UPPER
Rakib Fiha
fonte