我想要 grep 一个包含字符串的变量test
,但我还想确保它只能找到test
该行中唯一的单词。
因此,我尝试了这个:
string=test
echo "test" | grep "$string$"
我想知道是否grep
知道第一部分,$string
(在 grep “$字符串$”),要求查找字符串test
,而最后一部分$
(在 grep “$string” 中$“要求查找,但行中test
后面不应该有任何内容。是否可以区分为变量和仅作为行尾的正则表达式,还是我必须使用某种方式来区分它们?test
grep
$string
$
答案1
Grep 不知道它看不到的东西。如果 grep 看到$string$
,它将尝试匹配。所发生的事情是,shell 在启动之前$string{end-of-line}
扩展了变量,因此将 接收 为正则表达式。$string
grep
grep
test$
但是,给定单词$string$
,为什么最后一个$
is 没有被展开而
$string
is 却被展开了呢?因为$
不是一个有效的变量名。这在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$"