Як прописати великий аргумент командного рядка?


125

Я здійснив пошук ТА і виявив, що для великих ліній буде працювати наступний рядок

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

Але я спробував зробити аналогічну річ у аргументі командного рядка, який дав мені таку помилку

Спробував

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

Як ми могли це зробити?


8
Це працює для мене просто чудово. Опублікуйте весь сценарій, помилка, ймовірно, в іншому місці. Чи вказує твій шебанг bash?
манатура

Відповіді:


151

Синтаксис, str^^який ви намагаєтеся, доступний від Bash 4.0 і вище. Можливо, ваша старіша версія (або ви запустили сценарій із shявним чином):

Спробуйте це:

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

1
Зі слів mtk я зрозумів, що модифікація випадку насправді працює на нього зі змінними.
манатура

1
@manatwork Це не чітко сказано в початковому запитанні. Повідомлення про помилку заміни є таким же, як і у старих версіях bash.
Бернхард

4
Ви праві. Я перевірив версію, її 3.2.25. Ваше рішення працює, і я також спробував tr '[a-z]' [[A-Z]'.
mtk

20
@mtk Це повинно бути tr '[a-z]' '[A-Z]'.
l0b0

2
Я бігаю GNU bash, version 4.3.42(1)-release (x86_64-apple-darwin14.5.0), і я отримую ту ж помилку, що і ОП, тому я не думаю, що це доступно на будь-якому bash4.0 та вище, як ви кажете.
Гейт Межі

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

Вихід:

LOWERCASE

1
Я думаю, що POSIX не вимагає, /як в tr /a-z/ /A-Z/моїй редакції : це працює лише тому, що він замінює /, /але є марним: pubs.opengroup.org/onlinepubs/9699919799/utilities/tr.html Існує також більш незрозуміле і менш корисне tr '[:lower:]' '[:upper:]'.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Правильно. tr дуже різний, але він працює.
Дуг

umlauts не працюють з цим.
Євген

22

Будьте обережні з tr, якщо AZ - це все, що ви використовуєте. Для інших локалів навіть '[: нижня:]' '[: верхня:]' не вдається, працює лише awk's tapper і bash (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åäö

1
FWIW, tr '[:lower:]' '[:upper:]'зараз працює для вашого прикладу на OS X принаймні (також з LC_ALL=sv_SE)
Етан

1

Крім того, ви можете перейти на ksh або zsh, які підтримували перетворення справ протягом десятиліть (задовго до того bash, як ${var^^}додано 4.0), хоча з іншим синтаксисом:

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

(також працює з zsh; зауважте, що в pdksh / mksh це працює лише для літер ASCII).

З zsh, ви також можете використовувати Uпрапор розширення параметра:

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

POSIXLY, ви можете використовувати:

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

Також є:

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

Але в кількох реалізаціях, включаючи GNU tr, це працює лише для однобайтових символів (так, в локалі UTF-8, лише на листах ASCII).


0

Якщо хто - то до сих пір отримують намагаються помилки ${str^^}, ви можете спробувати python -cабо perlце, ймовірно , тому , що Баш версія нижче 4.

Але поки що bash 4 або більше працює швидко з існуючим рішенням.

L2U="I will be upper"

Використання python -cв bash

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

Аналогічно він також може бути використаний з великої літери :

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

Використання perl

echo $L2U | perl -ne 'print "\U$_"'
I WILL BE UPPER
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.