我有一个可能的文件扩展名数组,其中包含一些通配符,例如:
FILETYPE=("DBG"MSG"OUT"output*.txt"(
我还有一个文件列表,我从中获取文件扩展名。然后,我需要将扩展名与文件扩展名数组进行比较。
我试过:
if [[ ${EXTENSION} =~ "${FILETYPES[*]}" ]]; then
echo "file found"
fi
if [[ ${EXTENSION} == "${FILETYPES[*]}" ]]; then
echo "file found"
fi
和
if [[ ${EXTENSION} =~ "${FILETYPES[*]}" ]]; then
echo "file found"
fi
但是没有用
我试过了:
if [[ "${FILETYPES[*]}" =~ ${EXTENSION} ]]; then
echo "file found"
fi
然而,它最终将";txt";至";输出*.txt";并得出这是一场比赛的结论。
FILETYPES=("DBG" "MSG" "OUT" "output*.txt")
首先,避免使用all_CAPS变量名,除非这些变量是全局环境变量"output*.txt"
:可以作为globing模式,例如bash测试[[ $variable == output*.txt ]]
。但对于Regex匹配,它需要不同的语法,如[[ $variable =~ output.*.txt ]]
"${FILETYPES[*]}"
:将此数组扩展为single_string通常是一种不错的方法,但它需要巧妙地使用IFS
环境变量来帮助它扩展为Regex。类似于IFS='|' regex_fragment="(${array[*]})"
,这样每个数组条目都将被展开,用管道|
分隔,并作为(entry1|entry2|...)
括在括号中
以下是您可以使用的实现:
textscript.sh
#!/usr/bin/env bash
extensions_regexes=("DBG" "MSG" "OUT" "output.*.txt")
# Expands the extensions regexes into a proper regex string
IFS='|' regex=".*.(${extensions_regexes[*]})"
# Prints the regex for debug purposes
printf %s\n "$regex"
# Iterate all filenames passed as argument to the script
for filename; do
# Compare the filename with the regex
if [[ $filename =~ $regex ]]; then
printf 'file found: %s n' "$filename"
fi
done
示例用法:
$ touch foobar.MSG foobar.output.txt
$ bash testscript.sh *
.*.(DBG|MSG|OUT|output.*.txt)
file found: foobar.MSG
file found: foobar.output.txt
不能直接将字符串与数组进行比较。你能试试这样的东西吗:
filetypes=("DBG" "MSG" "OUT" "output*.txt")
extension="MSG" # example
match=0
for type in "${filetypes[@]}"; do
if [[ $extension = $type ]]; then
match=1
break
fi
done
echo "$match"
您可以使用regex
:保存循环
pat="^(DBG|MSG|OUT|output.*.txt)$"
extension="output_foo.txt" # example
match=0
if [[ $extension =~ $pat ]]; then
match=1
fi
echo "$match"
请注意,regex
的表达式与用于globbing的通配符不同
顺便说一句,我们通常不使用用户变量的大写字母,以避免与系统变量发生冲突。