Comment mettre l'argument en ligne de commande en majuscule?


125

J'ai cherché SO et trouvé que mettre en majuscule une chaîne suivante fonctionnerait

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

Mais j'ai essayé de faire la même chose avec un argument en ligne de commande, ce qui m'a donné l'erreur suivante

A essayé

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

Comment pourrions-nous faire cela?


8
Cela fonctionne très bien pour moi . Postez votre script entier, l'erreur est probablement ailleurs. Votre shebang pointe- basht-il?
— Manatwork

Réponses:


151

La syntaxe str^^que vous essayez est disponible à partir de Bash 4.0 et versions ultérieures. La vôtre est peut-être une version plus ancienne (ou vous avez exécuté le script avec shexplicitement):

Essaye ça:

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

1
D'après les mots de mtk, j'ai compris que la modification de cas fonctionne pour lui avec des variables.
— Manatwork

1
@manatwork Ce n'est pas clairement indiqué dans la question initiale. Le message d'erreur de substitution incorrecte est identique à celui que vous obtiendriez avec les versions antérieures de bash.
— Bernhard

4
Vous avez raison. J'ai vérifié la version 3.2.25. Votre solution fonctionne et j'ai aussi essayé tr '[a-z]' [[A-Z]'.
— MTK

20
@ MTK Cela devrait être tr '[a-z]' '[A-Z]'.
— l0b0

2
Je cours GNU bash, version 4.3.42(1)-release (x86_64-apple-darwin14.5.0), et j'obtiens la même erreur que OP, donc je ne pense pas que cela soit disponible sur les versions bash4.0 et supérieures comme vous le dites.
— Heath Borders

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

Sortie:

LOWERCASE

1
Je pense que POSIX n’a pas besoin du /comme tr /a-z/ /A-Z/avant mon édition: cela fonctionne car il remplace /par /mais est inutile: pubs.opengroup.org/onlinepubs/9699919799/utilities/tr.html Il existe également le plus obscur et le moins utile tr '[:lower:]' '[:upper:]'.
— Ciro Santilli a rejoint le forum

Correct. tr est très différent, mais ça marche.
— Doug

les trémas ne fonctionnent pas avec cela.
— Evgeny

22

Soyez prudent avec tr sauf si AZ est tout ce que vous utilisez. Pour les autres locales, même '[: lower:]' '' [: upper:] '' échoue, seuls Touk et bash (v4 +) de awk fonctionnent

$ 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:]'travaille maintenant pour votre exemple sur OS X au moins (aussi avec LC_ALL=sv_SE)
— Ethan

1

Vous pouvez également basculer vers ksh ou zsh, qui prennent en charge la conversion de cas depuis des décennies (bien avant que cela bashne soit ${var^^}ajouté à la version 4.0), avec une syntaxe différente:

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

(fonctionne également avec zsh; notez que dans pdksh / mksh, cela ne fonctionne que pour les lettres ASCII).

Avec zsh, vous pouvez également utiliser l' Uindicateur d'expansion de paramètre:

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

POSIXLY, vous pouvez utiliser:

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

Il y a aussi:

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

Mais dans quelques implémentations, y compris GNU tr, cela ne fonctionne que pour les caractères mono-octet (donc dans les locales UTF-8, uniquement sur les lettres ASCII).


0

Si quelqu'un essaie toujours d'erreur en essayant ${str^^}, vous pouvez essayer python -cou perlc'est probablement parce que la version de bash est inférieure à 4.

Mais jusqu’à présent, bash 4 ou plus fonctionne rapidement avec la solution existante.

L2U="I will be upper"

Utilisation python -cde bash

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

De même, il peut également être utilisé pour capitaliser avec:

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

En utilisant perl

echo $L2U | perl -ne 'print "\U$_"'
I WILL BE UPPER
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.