如何在Bash脚本中匹配完整的目录/文件名?
问题
我正在遍历目录,用以下脚本和包含目标匹配字符串的数组做校验:
matches=("README.md" "*.pdf" "item_output") while IFS= read -r -d '' i; do if [[ ${matches[*]} =~ $(basename $i) ]]; then echo $i fi done <<(find /home/user/somedir -print0)
原本只想匹配名为item_output的文件夹,结果连名为item的文件夹也被匹配到了,请问怎么修正实现仅匹配完整字符串?
解决方案
原脚本的问题在于${matches[*]} =~ $(basename $i)会把数组元素拼接成一个字符串进行正则匹配,item会被当成item_output的子串而匹配成功。要实现精确匹配(同时保留*.pdf这类通配符的功能),可以改成遍历matches数组,逐个用[[ ]]的==操作符判断——[[ $name == $pattern ]]支持通配符,且是完整匹配(而非子串匹配):
matches=("README.md" "*.pdf" "item_output") while IFS= read -r -d '' i; do filename=$(basename "$i") # 遍历匹配数组,逐个判断 for pattern in "${matches[@]}"; do if [[ "$filename" == "$pattern" ]]; then echo "$i" # 匹配到即跳出循环,避免重复输出 break fi done done <<(find /home/user/somedir -print0)
核心说明
- 使用
"${matches[@]}"遍历数组,确保每个元素被独立处理,避免空格分割导致的错误 [[ "$filename" == "$pattern" ]]的匹配逻辑:- 对于
README.md、item_output这类固定字符串,只有文件名完全一致时才会命中 - 对于
*.pdf这类通配符,会匹配所有以.pdf结尾的文件,符合原脚本的需求
- 对于
- 加入
break语句,避免同一个文件被多个匹配规则命中时重复输出
内容的提问来源于stack exchange,提问作者user10039647
相关产品推荐
相关产品推荐

