use*_*658 1 command-line regex grep
我想 grep 具有 string 的变量test,但我也想确保它只会找到它test是否是一行中唯一的单词。
所以,我试过这个:
string=test
echo "test" | grep "$string$"
Run Code Online (Sandbox Code Playgroud)
我想知道是否grep知道第一部分$string(在 grep " $string $" 中)要求查找 string test,而最后一部分$(在 grep "$string $ " 中要求查找 for test,但是test行后不应有任何内容。是否grep能够区$string分为变量,仅$作为行尾的正则表达式,还是必须使用某种方式将它们区分开?
Qua*_*odo 15
Grep 什么都不知道。如果 grep 看到$string$,它将尝试匹配$string{end-of-line}。发生的情况是 shell$string在grep启动之前扩展变量,因此它作为正则表达式grep接收
test$。
但是,给定这个词$string$,为什么最后一个$没有扩展
$string而是?因为$不是有效的变量名。这在POSIX 规范中非常清楚:
如果参数没有用大括号括起来,并且是一个名称, 则扩展应使用最长的有效名称(请参阅XBD 名称),无论该名称表示的变量是否存在。
和XBD 名称说明
在 shell 命令语言中,一个仅由可移植字符集中的下划线、数字和字母组成的单词。名称的第一个字符不是数字。
而且还有特殊的参数,如$$,$@,$#,等。
如果您不想记住所有这些,只需遵循Gordon Davisson 的建议
并避开所有$不应引入变量的内容,以确保将其保留。
$ echo "$string$"
test$
$ echo "$string\$"
test$
$ echo "\$string\$"
$string$
Run Code Online (Sandbox Code Playgroud)
还要记住变量在双引号中展开而不是在单引号中展开。
$ echo 'test' | grep '$string$' # No match, $string is not expanded
$ echo 'test' | grep "$string$" # Match, $string is expanded
test
Run Code Online (Sandbox Code Playgroud)
我想 grep 具有 string 的变量
test,但我也想确保它只会找到它test是否是一行中唯一的单词。
对于这一点,你需要或者正则表达式^test$(以锚绳都在开始和行结束),或使用-x的标志grep。您最初的尝试会匹配,Atest因为正则表达式test$未锚定到行首。
$ echo Atest | grep "$string$"
Atest
$ echo Atest | grep -x "$string"
$ echo Atest | grep "^$string$"
Run Code Online (Sandbox Code Playgroud)