Случай Bash соответствует проблеме со смешанными числами и буквами

Я пытаюсь позволить пользователю входить в размер, который будет использоваться в fallocate, таким образом, я должен удостовериться, что текст введен как 1G, 8G, 512M, и т.д.

У меня есть следующий код ниже; однако, все правильные форматы переходят к значению по умолчанию * случай.

echo -n "What amount do you want to allocate to the new swapfile? [i.e. 4G or 512M]\n"
read size
echo $size
case $size in

    [1-9][0-9]*[m|M|g|G] )
        echo "Size Verified: $size"
        ;;

    *) 
        echo "Invalid size: $size. Please use the format 1-999[M|G]. 
        ;;
esac

Я проверил свой regex с https://regexr.com/использование следующего ([1-9][0-9]*[m|M|g|G])

Примечание: Я знаю, что мое предупреждающее сообщение более строго, чем мой regex. Кроме того, я очень плохо знаком с ударом. Предоставьте дополнительные ссылки, которые я могу исследовать, если техника совершенствуется.

0
задан 29 July 2018 в 03:55

1 ответ

В первую очередь, case использование окружает шарики - которые отличаются от регулярных выражений. В частности, *?) подстановочные соответствия в себе, а не кванторах, которые влияют на предыдущий атом. Так, например:

  • основной regex:

    [0-9]? means 0 or 1 decimal digit
    [0-9]* means 0 or more decimal digits
    
  • простой шарик

    [0-9]? means a decimal digit followed by any single character
    [0-9]* means a decimal digit followed by any number of characters (including none)
    

Насколько я знаю, нет никакого способа указать произвольное число повторений в простом шарике оболочки. У Вас есть много опций:

  1. с помощью простых шариков оболочки соответствуйте каждой последовательности явно и ИЛИ их вместе. Для 1-3 цифр, например,

    case $1 in
      [0-9][mMgG]|[0-9][0-9][mMgG]|[0-9][0-9][0-9][mMgG])
        echo "simple glob match"
      ;;
      *)
        echo "no simple glob match"
      ;;
    esac
    
  2. используйте расширенный шарик удара, также [0-9]*([0-9]) (одна цифра сопровождается нулем или большим количеством цифр - подобная Вашему регулярному выражению), или +([0-9]) (одна или несколько цифр). Обратите внимание, что в отличие от regexes, квантор прибывает перед атомом, а не после.

    shopt -s extglob
    
    case $1 in
      +([0-9])[mMgG])
        echo "extended glob match"
      ;;
      *)
        echo "no extended glob match"
      ;;
    esac
    
  3. используйте регулярное выражение удара, но в a if ... then условное выражение

    if [[ $1 =~ [0-9][0-9]*[mMgG] ]]; then
      echo "regex match"
    else
      echo "no regex match"
    fi
    

В последнем случае Вы могли также использовать логику короткого замыкания:

[[ $1 =~ [0-9][0-9]*[mMgG] ]] && echo "regex match" || echo "no regex match"

Также обратите внимание на это в обоих шариках и regexes, [...] ряд символов не выражение так [m|M|g|G] не отличается от [mMgG|] и соответствует буквенным символам m, M, g, G и | (вероятно, не, что Вы хотите).

3
ответ дан 28 October 2019 в 06:28

Другие вопросы по тегам:

Похожие вопросы: