关于shell命令和grep的问题

时间:2011-05-06 19:18:49

标签: linux grep

有谁知道为什么

grep "p\{2\}" textfile

会在文件中找到“apple”,但

grep p\{2\} textfile

不会?

我是使用命令行和正则表达式的新手,这让我很困惑。

5 个答案:

答案 0 :(得分:2)

虽然这已经得到了解答,但由于您对所有这些内容都不熟悉,以下是如何调试它:

- 获取当前shell的pid(使用ps)。

 PID TTY          TIME CMD

 1611 pts/0    00:00:00 su

 1619 pts/0    00:00:00 bash

 1763 pts/0    00:00:00 ps

- 从其他shell中,将strace(系统调用跟踪器)附加到所需的pid(此处为1619):

strace -f -o <output_file> -p 1619

- 运行您尝试过的两个命令

- 打开输出文件并在此处查找所需流程的exec家庭电话:grep

我机器上的输出有点像:

1723  execve("/bin/grep", ["grep", "--color=auto", "p{2}", "foo"], [/* 19 vars */]) = 0

1725  execve("/bin/grep", ["grep", "--color=auto", "p\\{2\\}", "foo"], [/* 19 vars */]) = 0

现在你可以看到两种情况下grep的执行方式不同,可以自己解决问题。 :)

仍然是-e旗帜之谜尚未解决......

答案 1 :(得分:1)

如果没有引号,shell将尝试扩展选项。在你的例子中,大括号'{}'在shell中有一个特殊含义,就像星号'*'扩展为通配符一样。

答案 2 :(得分:0)

使用引号,您的完整正则表达式将直接传递给grep。如果没有引号,grep会将您的正则表达式视为p{2}

编辑:

为了澄清,在正则表达式传递给grep之前,如果没有引号,shell会删除斜杠。

尝试:

echo grep p\{2\} test.txt

你会看到你的输出......

grep p{2} test.txt

引号阻止shell在转到grep之前转义字符。你也可以逃避斜线,它可以不用引号 - grep p\\{2\\} test.txt

答案 3 :(得分:0)

来自grep手册页

In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose their special meaning; instead use the backslashed versions \?, \+, \{, \|, \(, and \).

所以这两个功能等同于

egrep p{2} 

grep "p\{2\}" 

第一个使用ERE(扩展正则表达式),第二个使用BRE(基本正则表达式),因为你使用grep(当你不使用-e开关时支持BRE)并且你用引号括起来所以“\ {”作为一个特殊的BRE角色扩展。

您的第二个实例无法正常工作,因为您只需查找文件中不存在的文字字符串2 {p}

你可以通过尝试来证明grep正在将你的字符串扩展为BRE:

grep "p\{2"

grep会抱怨

grep: Unmatched \{  

答案 4 :(得分:0)

第一个使用正则表达式,然后pp

使用模式
echo "apple" | grep 'p\{2\}'

第二个按字面意思模糊图案,然后是p{2}

echo "ap{2}le" | grep p\{2\}