Bash-将字符串与包含通配符的数组进行比较



我有一个可能的文件扩展名数组,其中包含一些通配符,例如:

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的通配符不同
顺便说一句,我们通常不使用用户变量的大写字母,以避免与系统变量发生冲突。

最新更新