标题基本上说明了一切,但我一生都无法弄清楚,并且对 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 ]]
检查。