bash – 如何检查文件名是否与shell脚本中的regex匹配
我有一个
shell脚本,需要检查文件名是否与某个正则表达式匹配,但它总是显示“不匹配”.谁能告诉我我的代码有什么问题?
fileNamePattern=abcd_????_def_*.txt realFilePath=/data/file/abcd_12bd_def_ghijk.txt if [[ $realFilePath =~ $fileNamePattern ]] then echo $realFilePath match $fileNamePattern else echo $realFilePath not match $fileNamePattern fi 解决方法
正则表达式与更简单的“glob”/“wildcard”/“normal”模式之间存在混淆 – 无论你想要什么称呼它们.你正在使用后者,但称之为正则表达式.
如果你想使用一个模式,你应该 >在分配1时引用它: fileNamePattern="abcd_????_def_*.txt" 你不想要任何东西扩展. $mypath="/mydir/myfile1.txt" $mypattern="myfile?.txt" $[[ $mypath == $mypattern ]] && echo "Matches!" || echo "Doesn't match!" Doesn't match! 但在将模式扩展为以*开头之后: $mypattern="*myfile?.txt" $[[ $mypath == $mypattern ]] && echo "Matches!" || echo "Doesn't match!" Matches! 第一个不匹配,因为它只匹配文件名,但不匹配完整路径.或者,您可以使用第一个模式,但使用parameter expansion删除路径的其余部分: $mypattern="myfile?.txt" $mypath="/mydir/myfile1.txt" $echo "${mypath##*/}" myfile1.txt $[[ ${mypath##*/} == $mypattern ]] && echo "Matches!" || echo "Doesn't match!" Matches! >使用==而不是=?,如上例所示.您也可以使用更多portable =,但由于我们已经使用非POSIX [[]]而不是[],我们也可以使用==. 如果你想使用正则表达式,你应该: >将您的模式写成一个:?和*在正则表达式中有不同的含义;他们修改了他们所追求的东西,而在水珠模式中,他们可以自立(见the manual).相应的模式将变为: fileNameRegex="abcd_.{4}_def_.*.txt" 并可以像这样使用: $realFilePath="/data/file/abcd_12bd_def_ghijk.txt" $[[ $mypath =~ $fileNameRegex ]] && echo "Matches!" || echo "Doesn't match!" Matches! >保持将正则表达式写入单独参数的习惯,然后在条件运算符[[]]中不加引号使用它,或者转义变得非常混乱 – 它在Bash版本中也更具可移植性. BashGuide有一个关于Bash中不同类型模式的great article. 请注意,引用您的参数几乎总是一个好习惯.在[[]]中的条件表达式中不需要它,并且实际上将右侧的解释抑制为模式或正则表达式.如果你使用[](它不支持正则表达式和模式),则需要引用以避免特殊字符和空字符串的意外副作用. 1实际上在这种情况下并不完全正确.分配给变量时,manual表示发生以下情况:
即,没有路径名(glob)扩展.虽然在这种情况下使用 fileNamePattern=abcd_????_def_*.txt 与引用的版本一样有效,使用引号可以防止在许多其他情况下出现意外,并且只要模式中有空白就需要使用引号. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |