我正在尝试允许用户输入将要使用的尺寸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
我已经检查过我的正则表达式https://regexr.com/使用以下([1-9][0-9]*[m|M|g|G])
注意:我知道我的警告信息比我的正则表达式更严格。另外,我对 bash 还很陌生。如果技术先进,请提供额外的链接,以便我可以研究。
答案1
首先,case
使用 shell 通配符 - 它与正则表达式不同。特别是,*
(和?
) 本身就是通配符匹配,而不是影响前一个原子的量词。例如:
基本正则表达式:
[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)
据我所知,没有办法在简单的 shell glob 中指定任意数量的重复。您有多种选择:
使用简单的 shell glob,明确匹配每个序列并将它们或在一起。例如,对于 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
使用 bash扩展的 glob,可以是
[0-9]*([0-9])
(一位数字后跟零个或多个数字 - 类似于正则表达式)或+([0-9])
(一位或多位数字)。请注意,与正则表达式不同,量词位于原子之前,而不是之后。shopt -s extglob case $1 in +([0-9])[mMgG]) echo "extended glob match" ;; *) echo "no extended glob match" ;; esac
使用 bash 正则表达式,但在
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"
还要注意,在 glob 和正则表达式中,[...]
都是一组字符而不是表达式,因此与文字字符、、和[m|M|g|G]
没有什么不同,并且匹配(可能不是您想要的)。[mMgG|]
m
M
g
G
|