grep和正则表达式存储在字符串中

时间:2016-11-16 18:10:04

标签: regex bash grep

我的问题很简短:

a="'[0-9]*'"
grep -E '[0-9]*' #for example, line containing 000 will be recognized and printed

grep -E $a #line containing 000 WILL NOT be printed, why is that?

替换grep正则表达式是否会改变命令的行为,还是从句法角度来看我错过了什么?换句话说,我如何使它使grep从存储在变量中的字符串接受正则表达式。

提前谢谢。

1 个答案:

答案 0 :(得分:0)

引用围绕数据,而不是 数据。这意味着,当您在变量中存储数据(在本例中为正则表达式)时,不要在变量中嵌入引号;相反,当你使用它时,在变量周围加上双引号:

a="[0-9]*"
grep -E "$a"

在使用变量时,你可以有时离开双引号(如在Avinash Raj的评论中),但它通常不安全。在这种情况下,只要当前工作目录中没有名称恰好以数字开头的文件或子目录,它就可以正常工作。你看,在$a周围没有双引号的情况下,shell将取其值,尝试将其拆分为多个单词(这里不是问题),尝试将包含shell通配符的每个单词扩展为匹配文件列表(这里有潜在的问题),并将那个传递给命令(grep)作为其参数列表。这意味着如果你碰巧有当前目录中以数字开头的文件,grep认为你运行了这样的命令:

grep -E 1file.txt 2file.jpg 3file.etc

...它将第一个文件名视为要搜索的模式,将任何其他文件名视为要搜索的文件。并且你会想知道为什么你的脚本工作或失败取决于你碰巧在哪个目录。

注意:模式[0-9]*是一个有效的正则表达式,是一个有效的shell glob(通配符)模式,但它在两个上下文中意味着非常不同的东西。作为正则表达式,它表示连续0位或更多位数。作为一个shell glob,它意味着以数字开头的东西。说到这一点,grep -E '[0-9]*'实际上并不是非常有用,因为所有包含0位或更多位的字符串,因此它会匹配您提供的每个文件的每一行