我正在用一种高级编程语言编写一个wildcardMatch(input, pattern)
函数,我希望它的工作方式与 Unix 中的 glob 匹配完全一样。
为此,我一直使用基于属性的测试来生成随机输入,并根据我的实现和 Unix 实现对其进行测试,然后比较它们的返回值是否相同。
我的问题是我不信任我的简单 Unix 帮助程序脚本:
#!/bin/bash
## Created for development/testing
##
## Example Usage:
## ./wildcard_test.sh "foobar" "fooba*"
string=$1
pattern=$2
if [[ $string == $pattern ]]; then
echo 0
exit 0
else
echo 1
exit 1
fi
一切都工作正常,直到我了解到扩展将在脚本实际运行之前发生:
./wildcart_test.sh "foo" "???"
在该示例中,问号将扩展为实际匹配该目录中的其他文件,从而导致==
比较失败。lib
例如,在本例中,它扩展到。
有没有更好的方法来测试全局匹配?
答案1
不,
./wildcart_test.sh "foo" "???"
正如所???
引用的那样,没有问题,因此不会被您的 shell 扩展。但请注意,双引号内的\
,$
和字符仍然是特殊的。`
您可能想要使用单引号,其中没有特殊字符(在类似 Bourne 的 shell 中)。
不过,您可以在这里做的一件事是删除bash
依赖项并使用标准sh
语法来执行此操作:
#! /bin/sh -
subject=${1?No subject} pattern=${2?No pattern}
case $subject in
($pattern) echo 1; true;;
(*) echo 0; false;;
esac
请注意,虽然0
退出状态表示 true,更习惯使用 0数字为假,非零为真。
但请注意sh
,为了可移植,[^x]
需要编写with ,[!x]
因为[^x]
它仍然不是标准的。
而\
in是否$pattern
被模式匹配代码特殊对待也取决于实现和版本。that-script '\foo' '\*'
可能在某些情况下返回 false,而在其他情况下返回 true。同样对于that-script '*' '\*'
.
要匹配文字反斜杠,请使用that-script '\foo' '[\\]*'
.要匹配通配符 ( ?
, *
, [
),请使用that-script '*?[' '[*][?][[]'
。还要注意 Bourne shell 及其后代(ksh88、ksh93)中的错误/错误功能: 和that-script a '[a]'
都会that-script '[a]' '[a]'
返回真的/bin/sh
在基于 AT&T ksh 的系统上。