【问题标题】:Native bash regexp [[ $f =~ "^[^\.]+$" ]] never matching本机 bash 正则表达式 [[ $f =~ "^[^\.]+$" ]] 从不匹配
【发布时间】:2015-08-31 18:27:26
【问题描述】:

我目前正在尝试使用 bash 遍历某个目录中的所有文件。如果文件与以下正则表达式匹配,则输出文件名。如果没有,它会输出'not',然后是文件名。正则表达式应该过滤掉任何带有“。”的文件。在他们里面。

for f in * ; do
    if [[ $f =~ "^[^\.]+$" ]]; then
        echo "$f"
    else
        echo "not $f"
    fi                                                                                                           
done

它正确地循环遍历所有文件,但由于一个让我难过一段时间的原因,我不能让它只排除带有“。”的文件。在他们中。例如,在包含以下文件的目录中:

bashrc
gitconfig
install.sh
README.md
vimrc

脚本的输出是这样的:

not bashrc
not gitconfig
not install.sh
not README.md
not vimrc

我验证了正则表达式here。有什么想法吗?

【问题讨论】:

    标签: regex linux bash loops


    【解决方案1】:

    不要引用表达式的右侧。

    if [[ $f =~ ^[^.]+$ ]]; then
    

    引号使字符串成为文字子字符串,而不是正则表达式。 为了更好地跨 bash 版本的可移植性,请将您的正则表达式放在一个变量中(单引号,这将使反斜杠文字):

    re='^[.]+$'
    if [[ $f =~ $re ]]; then
    

    也就是说,您也可以使用 extglob 来做到这一点:

    shopt -s extglob # enable extended globs
    for f in +([!.]); do
      printf 'Matched %q\n' "$f"
    done
    

    ...或使用通用模式匹配:

    for f in *; do
        if [[ $f = *.* ]]; then
            printf '%q contains a dot\n' "$f"
        else
            printf '%q does not contain a dot\n' "$f"
        fi
    done
    

    【讨论】:

    • 非常感谢!我新它会像那样简单。
    • 如果我一开始就写这篇文章,我可能会选择 [[ $f =~ \. ]] 并反转块。
    • @EtanReisner, ...或[[ $f = *.* ]]
    猜你喜欢
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 2023-03-14
    • 2014-08-10
    • 2021-06-23
    • 2013-08-06
    相关资源
    最近更新 更多