我想创建一个如下数组,以检查输出文件名是否与数组中的模式匹配。
declare -a arr=('class*_1n_*000000.txt','class*_1n_*010000.txt','class*_2n_*010000.txt','class*_2n_*012000.txt','class*_3n_*235000.txt')
if [[ "${arr[*]}"==$output_filename ]]; then
echo $output_filename exist in arr
#do something...
else
echo $output_filename not exist in arr
#do something...
fi
我已经尝试了以下3个案例,而评论将是我的预期结果
output_filename='class_2n_20180922012000.txt' #exist
output_filename='classA_2n_20180923012000.txt' #exist
output_filename='classA_4n_20180923012000.txt' #not exist
但所有三种情况都存在。
如何解决此问题?
任何帮助将不胜感激:)
答案 0 :(得分:1)
好的,首先让我们解决几个基本的shell语法问题。数组声明:
declare -a arr=('class*_1n_*000000.txt','class*_1n_*010000.txt','class*_2n_*010000.txt','class*_2n_*012000.txt','class*_3n_*235000.txt')
不起作用,因为bash不使用逗号分隔数组的元素,而是使用空格。由于那里没有空格,因此外壳程序会将其视为一个大数组元素,其中恰好包含一些逗号。您想要这个:
declare -a arr=('class*_1n_*000000.txt' 'class*_1n_*010000.txt' 'class*_2n_*010000.txt' 'class*_2n_*012000.txt' 'class*_3n_*235000.txt')
第二,比较:
if [[ "${arr[*]}"==$output_filename ]]; then
根本没有做任何您想做的事情。同样,空格是shell语法中的定界符,并且由于周围没有空格,==
不会被视为运算符,因此它只是单个长字符串的一部分。 [[ somestring ]]
进行测试以查看字符串是否为非空白,并且由于该字符串不是空白,因此测试始终以true表示。现在,明显的解决方法是:
if [[ "${arr[*]}" == $output_filename ]]; then
...至少进行比较,但不进行所需的比较。它将数组的整个内容(所有元素之间都留有空格,因为[*]
就是这样)视为单个字符串,并查看它是否与$output_filename
匹配,其中$output_filename
被视为通配符模式。但您希望将数组元素视为通配符模式,因此需要将其反转:
if [[ "$output_filename" == ${arr[*]} ]]; then
...但这不是您想要的 ,因为它正在检查$output_filename
是否与arr
中所有条目的 all 相匹配粘在一起。为了使其匹配,$output_filename
必须是由五个文件名组成的列表,并用空格分隔,第一个匹配的class*_1n_*000000.txt
,第二个匹配的class*_1n_*010000.txt
等。您需要一次将文件名与每个数组元素进行比较,并跟踪是否找到匹配项。像这样:
found_match="false"
for pattern in "${arr[@]}"; do
if [[ "$output_filename" == $pattern ]]; then
found_match="true"
break
fi
done
if [[ "$found_match" == true ]]; then
echo "$output_filename exist in arr"
#do something...
else
echo "$output_filename not exist in arr"
#do something...
fi
请注意,"${arr[@]}"
(注意双引号和@
)扩展到数组的每个元素,每个元素都被视为一个单独的字符串(因此for
会在它们上进行迭代) 。另外,我在要打印的字符串两边加上了双引号。您几乎总是希望在变量引用(或包含变量引用的内容)两边加上双引号,以避免意外的通配符扩展等。但是,这里有一个例外:在[[ "$output_filename" == $pattern ]]
中,$pattern
必须保留不带引号,以便将其视为通配符模式而不是固定字符串。