在Shell脚本中,case
语句允许使用通配符进行模式匹配,这对于编写基于用户输入或其他变量值进行分支决策的脚本非常有用。下面是如何在case
语句中使用通配符(如*
、?
和[]
)进行匹配的示例和说明:
shell
#!/bin/bash
read -p "Enter a filename: " filename
case "$filename" in
*.txt)
echo "You entered a text file."
;;
*.[ch])
echo "You entered a C source or header file."
;;
???.*)
echo "You entered a three-character filename prefix followed by any extension."
;;
*)
echo "No specific pattern matched. You entered: $filename"
;;
esac
详解:
-
case "$filename" in
: 开始case
语句,其中"$filename"
是要进行匹配的变量或表达式。 -
*.txt)
: 第一个模式使用通配符*
匹配任何以.txt
结尾的字符串。如果$filename
符合这个模式,执行该模式下的命令(此处为echo "You entered a text file."
)。 -
*.[ch])
: 第二个模式使用*
匹配任何字符序列,后面紧跟.
和方括号中的字符类[ch]
,表示匹配以.c
或.h
结尾的字符串,即C源文件或头文件。匹配成功则执行相应命令。 -
???.*)
: 第三个模式使用连续两个?
匹配任意两个字符,紧接着一个.
和*
,表示匹配以任意三个字符开头且之后有任意扩展名的文件名。 -
*)
: 这是一个默认模式,当前面的所有模式都不匹配时执行。在此处,它表示如果$filename
没有匹配到前面任何一个模式,则输出“无特定模式匹配”的信息。 -
;;
: 结束每个模式的定义。每个模式及其关联命令块必须以;;
结束。
运行此脚本并输入不同的文件名,观察case
语句如何根据输入与各模式进行匹配并执行相应的命令。
请注意,case
语句中的通配符匹配是基于Shell的文件名扩展规则,而不是正则表达式。因此,可用的通配符较为有限,主要包括:
*
: 匹配零个或多个任意字符。?
: 匹配单个任意字符。[ ]
: 匹配括号内的任何一个字符。例如,[abc]
匹配'a'、'b'或'c'。还可以指定范围,如[0-9]
匹配任何数字。[! ]
: 匹配不在括号内的任何一个字符。例如,[!abc]
匹配除'a'、'b'、'c'之外的任何字符。
合理运用这些通配符,可以使case
语句更加灵活地处理多种输入情况。