在 bash 脚本中,使用 =~,如何匹配正则表达式 ^#.*${new_user}?

在 bash 脚本中,使用 =~,如何匹配正则表达式 ^#.*${new_user}?

标题基本上说明了一切,但我一生都无法弄清楚,并且对 bash 正则表达式匹配感到困惑。这是if我在 bash 脚本中的语句,但它始终匹配该行${new_user}而不是# ${new_user}.我基本上想匹配一个“注释掉”的用户。

if [[ $(<"foo.txt") =~ \#.*${new_user} ]]; then

答案1

对于此模式,不使用正则表达式而仅使用 glob 表达式要简单得多。这相当于^#.*${new_user}你的问题:

% new_user=foo
% [[ '# somethingfoo' == '#'*"${new_user}"* ]]; echo $?
0
% [[ '# somethingbar' == '#'*"${new_user}"* ]]; echo $?
1

由于您仅锚定问题的一侧,因此听起来您想匹配 后的任意字符$new_user。如果您确实想在最后锚定,请删除*.

虽然在 bash 中使用正则表达式当然是可能的,但其人体工程学和枪法却相当尴尬。如果可能的话,我强烈建议使用 glob 或其他机制。

如果您确实需要使用正则表达式,请按以下方法操作(唯一的区别是${new_user}在包含正则表达式字符的情况下引用):

$ [[ '# somethingfoo' =~ ^#.*"${new_user}" ]]; echo $?
0
$ [[ '# somethingbar' =~ ^#.*"${new_user}" ]]; echo $?
1

再次强调,如果您想在末尾进行锚定,请添加一个$.


您也可能误解了^多行上下文中的含义。在 bash 中,^匹配字符串的开头,而不是行的开头。如果您需要查看每一行以确定是否存在某些内容,请使用if grep ...; then, 或以下循环:

found=0
while IFS= read -r line || [[ $line ]]; do
    if [[ "$line" == '#'*"${new_user}"* ]]; then
        found=1
        break
    fi
done < foo.txt

# do something with $found

如果您不关心最后没有换行符的文件,则可以省略该[[ $line ]]检查。

相关内容