Jak wpisać duże litery do argumentu wiersza poleceń?

125

Przeszukałem SO i stwierdziłem, że wielkie litery będą działać

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

Ale próbowałem zrobić podobną rzecz w argumencie wiersza poleceń, co dało mi następujący błąd

Wypróbowany

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

Jak możemy to zrobić?

Mt.
źródło
8
To działa na mnie dobrze. Opublikuj cały skrypt, błąd prawdopodobnie występuje gdzie indziej. Czy twój shebang wskazuje bash?
manatwork
możliwe tak samo jak: stackoverflow.com/questions/2264428/...
Ciro Santilli 23 改造 中心 法轮功 六四 事件

Odpowiedzi:

151

Próbowana przez str^^ciebie składnia jest dostępna w wersji Bash 4.0 i nowszych. Być może twoja jest starszą wersją (lub uruchomiłeś skrypt shjawnie):

Spróbuj tego:

str="Some string"
printf '%s\n' "$str" | awk '{ print toupper($0) }'
Guru
źródło
1
Ze słów MTK zrozumiałem, że modyfikacja wielkości liter faktycznie działa dla niego ze zmiennymi.
manatwork
1
@manatwork Nie jest to wyraźnie określone w pytaniu początkowym. Komunikat o błędnym podstawieniu jest taki sam, jak w przypadku starszych wersji bash.
Bernhard
4
Masz rację. Sprawdziłem wersję 3.2.25. Twoje rozwiązanie działa, a także próbowałem tr '[a-z]' [[A-Z]'.
mtk
20
@mtk To powinno być tr '[a-z]' '[A-Z]'.
l0b0
2
Pracuję GNU bash, version 4.3.42(1)-release (x86_64-apple-darwin14.5.0)i otrzymuję ten sam błąd co OP, więc nie sądzę, że jest to dostępne w żadnej wersji bash4.0 i wyższej, jak mówisz.
Heath Borders
79
echo "lowercase" | tr a-z A-Z

Wynik:

LOWERCASE
Johner Ramirez
źródło
1
Myślę POSIX nie wymaga /jak w tr /a-z/ /A-Z/przed moim edit: to właśnie działa, ponieważ zastępuje /przez /ale jest bezużyteczny: pubs.opengroup.org/onlinepubs/9699919799/utilities/tr.html Istnieje również istnieje bardziej niejasne i mniej użyteczne tr '[:lower:]' '[:upper:]'.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
Poprawny. tr jest bardzo różne, ale działa.
Doug
umlauts nie działają z tym.
Jewgienij
22

Uważaj na tr, chyba że używasz tylko AZ. W przypadku innych ustawień regionalnych nawet „[: dolny:]” „[: górny:]” nie działa, działa tylko tupper i bash awk (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
źródło
1
FWIW, tr '[:lower:]' '[:upper:]'pracuje teraz dla twojego przykładu na OS X przynajmniej (także z LC_ALL=sv_SE)
Ethan
1

Alternatywnie, można przełączyć się do ksh lub zsh które miały case wsparcie konwersji dziesięcioleci (na długo przed bash„s ${var^^}dodanych w wersji 4.0), choć z różną składnię:

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

(działa również z zsh; zauważ, że w pdksh / mksh, który działa tylko dla liter ASCII).

Za pomocą zshmożna również użyć Uflagi ekspansji parametrów:

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

POSIXLY możesz użyć:

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

Jest także:

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

Ale w kilku implementacjach, w tym GNU tr, działa to tylko dla znaków jednobajtowych (tak więc w ustawieniach regionalnych UTF-8, tylko dla liter ASCII).

Stéphane Chazelas
źródło
0

Jeśli ktoś nadal otrzymuje komunikat o błędzie ${str^^}, możesz spróbować python -club perlPrawdopodobnie, ponieważ wersja bash jest mniejsza niż 4.

Ale jak dotąd bash 4 lub nowszy działa szybko z istniejącym rozwiązaniem.

L2U="I will be upper"

Używanie python -cw bashu

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

Podobnie można go również użyć do wielkich liter :

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

Za pomocą perl

echo $L2U | perl -ne 'print "\U$_"'
I WILL BE UPPER
Rakib Fiha
źródło