Принимает только 4-символьные десятичные числа в качестве пользовательского ввода для чтения

#linux #bash #shell #decimal #posix

#linux #bash #оболочка #десятичные #posix

Вопрос:

Я пишу небольшой скрипт, чтобы легко фиксировать веса, которые берутся из пользовательского ввода с помощью read -p .

Я хочу, чтобы все записанные веса были длиной в 4 символа, десятичные числа в формате XX.X. Например, 30,2 кг.

 #!/bin/bash

# take input from prompt (-p) and store it in $varweight
read -p 'Enter weight in kg: ' varweight
  

Как я могу убедиться, что пользователи могут вводить десятичные числа только в этом формате?

Спасибо за вашу помощь.

Комментарии:

1. А если вес < 10?

Ответ №1:

Одним из способов было бы использовать регулярное выражение и указывать длину для удаления ложных срабатываний (необязательно). Конечно, для приведенного ниже потребуется bash оболочка, потому что ~ не соответствует POSIX

 str="30.4"
re='^[[:digit:]]{2}.[[:digit:]]$'

if [[ $str =~ $re ]]; then
    echo 'true'
fi
  

Хотя в оболочке, совместимой с POSIX, вы могли бы использовать case оператор

 case $str in  
   [0-9][0-9].[0-9]) echo good ;; 
   *) echo bad;; 
esac
  

Гораздо лучшим инструментом, совместимым с POSIX, было бы использовать expr для сопоставления регулярных выражений.

 if expr "$str" : '[[:digit:]]{2}.[[:digit:]]$' > /dev/null; then
    echo "true"
fi
  

Комментарии:

1. Используйте expr для проверки str , а не разбивайте его пополам и проверяйте длину каждого компонента (что не отсеивает недопустимые входные данные, такие как xy.z ). if expr "$str" : '[[:digit:]]{2}.[[:digit:]]$' > /dev/null; then .

2. @chepner: Совместимо ли условие if с ((..)) POSIX тоже? Я думаю, что да

3. Нет. В POSIX есть арифметические выражения ( $((...)) ), но нет арифметической составной команды ( ((...)) ).

4. case Оператор в порядке; кроме того, . не обязательно использовать escape, поскольку он не имеет особого значения в шаблоне.