gpt4 book ai didi

bash - 如何检查文件名是否与 shell 脚本中的正则表达式匹配

转载 作者:行者123 更新时间:2023-11-29 09:07:49 26 4
gpt4 key购买 nike

我有一个 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”/“通配符”/“正常”模式 之间存在混淆——随便你怎么调用它们。您正在使用后者,但将其称为正则表达式。

如果你想使用模式,你应该

  • 赋值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!
  • 如上例所示,使用== 而不是=~。您也可以使用更便携的 = 代替,但由于我们已经在使用非 POSIX [[ ]] 而不是 [ ] ,我们也可以使用 ==

如果你想使用正则表达式,你应该:

  • 将您的模式写成一个:?* 在正则表达式中具有不同的含义;他们修改他们所代表的东西,而在 glob 模式中,他们可以独立存在(参见 the manual )。相应的模式将变为:

      fileNameRegex='abcd_.{4}_def_.*\.txt'

    可以这样使用:

      $ mypath="/data/file/abcd_12bd_def_ghijk.txt"
    $ [[ $mypath =~ $fileNameRegex ]] && echo "Matches!" || echo "Doesn't match!"
    Matches!
  • 保持将正则表达式写入单独参数的习惯,然后在条件运算符 [[ ]] 中不加引号使用它,否则转义会变得非常困惑——它在 Bash 中也更可移植版本。

BashGuide 有一个 great article关于 Bash 中不同类型的模式。

请注意,引用参数几乎总是一个好习惯。 [[ ]] 中的条件表达式不需要它,实际上禁止将右侧解释为模式或正则表达式。如果您使用的是 [ ](无论如何都不支持正则表达式和模式),则需要引用以避免特殊字符和空字符串的意外副作用。


1 实际上,在这种情况下完全不正确。分配给变量时,manual表示会发生以下情况:

[...] tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal [...]

即,没有路径名(glob)扩展。虽然在这种情况下使用

fileNamePattern=abcd_????_def_*.txt

与引用的版本一样有效,在许多其他情况下使用引号可以防止意外,并且一旦模式中有空白就需要使用引号。

关于bash - 如何检查文件名是否与 shell 脚本中的正则表达式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37037767/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com