本机bash regexp[[$f=~";^[^\.]和#x2B;$”从不匹配

本机bash regexp[[$f=~";^[^\.]和#x2B;$”从不匹配,regex,linux,bash,loops,Regex,Linux,Bash,Loops,我目前正在尝试使用bash遍历某个目录中的所有文件。如果文件与以下正则表达式匹配,则输出文件名。如果没有,则输出“not”,然后输出文件名。正则表达式应该过滤掉所有包含“.”的文件 for f in * ; do if [[ $f =~ "^[^\.]+$" ]]; then echo "$f" else echo "not $f" fi

我目前正在尝试使用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

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

不要引用你表达的右侧

if [[ $f =~ ^[^.]+$ ]]; then
引号使字符串成为文字子字符串,而不是正则表达式。 为了更好地跨bash版本移植,请将正则表达式放入变量中(单引号,这将使反斜杠变成文字):


也就是说,您也可以使用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

不要引用你表达的右边

if [[ $f =~ ^[^.]+$ ]]; then
引号使字符串成为文字子字符串,而不是正则表达式。 为了更好地跨bash版本移植,请将正则表达式放入变量中(单引号,这将使反斜杠变成文字):


也就是说,您也可以使用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=*.]]]
。非常感谢!我想它应该是这样简单的。如果我当初写这篇文章的话,我可能会选择
[[$f=~\.]]
并反转块。@EtanReisner,…或者
[[$f=*.]]