grep 是否区分变量和 $ 正则表达式?

grep 是否区分变量和 $ 正则表达式?

我想要 grep 一个包含字符串的变量test,但我还想确保它只能找到test该行中唯一的单词。

因此,我尝试了这个:

string=test
echo "test" | grep "$string$"

我想知道是否grep知道第一部分,$string(在 grep “$字符串$”),要求查找字符串test,而最后一部分$(在 grep “$string” 中$“要求查找,但行中test后面不应该有任何内容。是否可以区分为变量和仅作为行尾的正则表达式,还是我必须使用某种方式来区分它们?testgrep$string$

答案1

Grep 不知道它看不到的东西。如果 grep 看到$string$,它将尝试匹配。所发生的事情是,shell 在启动之前$string{end-of-line}扩展了变量,因此将 接收 为正则表达式。$stringgrepgreptest$

但是,给定单词$string$,为什么最后一个$is 没有被展开而 $stringis 却被展开了呢?因为$不是一个有效的变量名。这在POSIX 规范

如果参数没有用括号括起来,并且是一个名称, 扩展应使用最长的有效名称(看XBD 名称),无论该名称所代表的变量是否存在。

XBD 名称状态

在 shell 命令语言中,一个仅由可移植字符集中的下划线、数字和字母组成的单词。名称的第一个字符不是数字。

还有特殊参数,例如$$,,,$@等等$#

如果你不想记住这一切,只需关注戈登·戴维森的建议 并转义每个$不应引入变量的变量以确保它将被保留。

$ echo "$string$"
test$
$ echo "$string\$"
test$
$ echo "\$string\$"
$string$

还要记住,变量在双引号中扩展,但在单引号中不扩展。

$ echo 'test' | grep '$string$'   # No match, $string is not expanded    
$ echo 'test' | grep "$string$"   # Match, $string is expanded
test

我想要 grep 一个包含字符串的变量test,但我还想确保它只能找到test该行中唯一的单词。

为此,您需要正则表达式^test$(将字符串锚定到行首和行末)或使用-x旗帜grep。您最初的尝试将会匹配,Atest因为正则表达式test$没有锚定到行首。

$ echo Atest | grep "$string$"
Atest
$ echo Atest | grep -x "$string"
$ echo Atest | grep "^$string$"

相关内容