Mac Automator中Bash正则匹配文件扩展名异常问题咨询
问题原因与解决方法
1. 正则匹配逻辑的问题
你的正则.*\.(pdf|doc|docx|rtf)的匹配逻辑是:
.*:匹配任意数量的任意字符(包括空字符)\.:匹配一个点号(pdf|doc|docx|rtf):匹配括号内的任意一个字符串
但这个正则没有锚定字符串的结尾,所以只要文件名(或文件路径)的任意位置出现.pdf、.doc、.docx或.rtf这类子串,就会触发匹配。比如文件名是"my.doc.file.txt"时,中间的.doc子串会被命中;如果文件路径里包含类似"documents"的文件夹名,路径中的.doc部分也会导致误判。
你提到"my txt file.ddd"也被匹配,大概率是因为Automator中$f变量传递的不是单纯文件名,而是文件的完整POSIX路径,若路径里包含"doc""rtf"这类子串,就会被正则误匹配。
2. Automator与在线Bash环境的差异
在线Bash环境中你直接赋值f="my txt file.ddd",变量内容是纯文件名,正则自然不会匹配;但Automator里$f默认传递的是文件完整路径,若路径包含匹配子串就会误判。另外,Mac系统默认shell是zsh,若你的Automator脚本没明确指定用bash(开头没有#!/bin/bash),zsh的正则匹配行为也可能和bash存在细微差异,但核心问题还是缺少结尾锚定。
3. 修正后的脚本
要准确匹配文件名末尾的扩展名,需给正则加上结尾锚定$,同时可针对多点点文件名做优化,修正后的判断如下:
基础修正版
#!/bin/bash if [[ $f =~ \.(pdf|doc|docx|rtf)$ ]] then # 此处编写你的操作代码 fi
严谨版(处理多点点文件名)
针对"file.name.pdf"这类包含多个点的文件名,确保匹配最后一个点后的扩展名:
#!/bin/bash if [[ $f =~ [^.]+\.(pdf|doc|docx|rtf)$ ]] then # 此处编写你的操作代码 fi
仅匹配文件名(排除路径干扰)
如果要完全忽略路径,只基于文件名判断,可先提取文件名:
#!/bin/bash filename=$(basename "$f") if [[ $filename =~ \.(pdf|doc|docx|rtf)$ ]] then # 此处编写你的操作代码 fi
4. 修正后匹配范围说明
修正后的正则\.(pdf|doc|docx|rtf)$只会匹配字符串末尾的点加指定扩展名:
- 匹配:
report.pdf、notes.docx、file.name.rtf - 不匹配:
mydoc.txt、my txt file.ddd、path/to/documents/file.txt
内容的提问来源于stack exchange,提问作者Gerti
相关产品推荐
相关产品推荐

