Перевірте довжину змінної


27

Я повинен перевірити довжину читання змінної (мій скрипт обмежений п’ятьма вставленими символами), я думаю про щось подібне:

#!/bin/bash
read string
check=${#string}
echo $check
if [ $check -ge 5 ]; then echo "error" ; exit
else echo "done"
fi

чи є більш «елегантне» рішення?


1
Ваш сценарій працює правильно у стандартному POSIX /bin/sh. Вам слід подумати про зміну лінії shebang, щоб #!/bin/shвона була більш портативною та працювала в середовищах, де bash недоступний. Плюс, /bin/shможе бути більш легка оболонка, як тире, яка не обтяжена функціями, призначеними для інтерактивного використання.
Селада

@Celada, правда, хоча в цьому випадку dash's ${#string}дасть вам довжину в кількості байтів замість символів.
Стефан Шазелас

Відповіді:


43

Більш елегантний? Ні

Коротше? Так :)

#!/bin/bash
read string
if [ ${#string} -ge 5 ]; then echo "error" ; exit
else echo "done"
fi

І якщо у вас немає проблем торгувати більш елегантністю на користь того, щоб бути коротшими, ви можете мати сценарій на 2 рядки менше:

#!/bin/bash
read string
[ ${#string} -ge 5 ] && echo "error" || echo "done"

Ви можете використовувати подвійні дужки, якщо вважаєте, що це безпечніше. Пояснення тут .


3

Сумісна з Bourne альтернатива ( ${#string}це POSIX, але не Bourne (не те, що ви, ймовірно, коли-небудь стикаєтеся з оболонкою Bourne в ці дні)):

case $string in
  ?????*) echo >&2 Too long; exit 1;;
       *) echo OK
esac

Зауважте, що і для обох, ${#string}і ????чи буде це кількість байтів або символів, буде залежати від оболонки. Як правило (і це вимагає POSIX), це кількість символів. Але для таких оболонок dash, які не знають багато байтів, вони будуть натомість байтами.

З mksh, вам потрібно set -o utf8-mode(в локалях UTF-8), щоб він зрозумів багатобайтові символи:

$ string=€€€ bash -c 'echo "${#string}"'
3
$ string=€€€ dash -c 'echo "${#string}"'
9
$ string=€€€ mksh -c 'echo "${#string}"'
9
$ string=€€€ mksh -o utf8-mode -c 'echo "${#string}"'
3
$ locale charmap
UTF-8

поза темою, але echo Too longвідрізняється під капотом відecho 'Too long'
Стівен Пенні

І, якщо ви просто надрукуєте, коли це "занадто довго", я можу зробити ще більше компактний ifваріант на моєму варіанті :)

2
@StevenPenny, echo Too longпередає два аргументи ( Tooі long), до echoяких echoвиводиться розділене пробілом (а за ним новий рядок), в той час як в echo 'Too long', ми передаємо один Too longаргумент, до echoякого він відображається, слідуючи за новим рядком. Отже, це функціонально рівнозначно.
Стефан Шазелас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.