Как прописать прописные буквы аргумента командной строки?


125

Я искал SO и обнаружил, что в верхнем регистре будет работать следующая строка

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?
manatwork

Ответы:


151

Синтаксис, str^^который вы пытаетесь использовать, доступен в Bash 4.0 и выше. Возможно, у вас более старая версия (или вы запустили скрипт shявно):

Попробуй это:

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

1
Со слов mtk я понял, что модификация падежа у него действительно работает с переменными.
manatwork

1
@manatwork Это не ясно указано в первоначальном вопросе. Сообщение об ошибке неправильной замены такое же, как и в старых версиях bash.
Бернхард

4
Ты прав. Я проверил версию, ее 3.2.25. Ваше решение работает, и я тоже попробовал tr '[a-z]' [[A-Z]'.
MTK

20
@mtk Это должно быть tr '[a-z]' '[A-Z]'.
10

2
Я бегу GNU bash, version 4.3.42(1)-release (x86_64-apple-darwin14.5.0)и получаю ту же ошибку, что и OP, поэтому я не думаю, что она доступна на любой bashверсии 4.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:]'.
Сиро Сантилли 新疆 新疆 中心 法轮功 六四 事件

Верный. Тр очень отличается, но это работает.
Даг

Умлауты не работают с этим.
Евгений

22

Будьте осторожны с tr, если только AZ не все, что вы используете. Для других локалей даже '[: lower:]' '[: upper:]' не работает, работает только touk и bash (v4 +) в 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:]'сейчас работает для вашего примера на 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скорее всего, потому что версия bash ниже 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.