2011-05-06 139 views
3

有誰知道爲什麼問題有關shell命令和grep

grep "p\{2\}" textfile 

會發現 「蘋果」,如果它在文件中,但

grep p\{2\} textfile 

不會呢?

我是使用命令行和正則表達式的新手,這讓我很困惑。

+2

我認爲你做了一個更有趣的發現貼在下面的答案。 grep不應該支持你在沒有-e開關的情況下進行輸入,但是如果你用引號括起來的話,grep應該不會支持。我會繼續尋找,但會有興趣看到答案是什麼。 – nsfyn55 2011-05-06 19:32:10

+0

@ nsfyn55:grep完美支持zjmiller輸入的內容。在上述情況下,如果未指定'e'選項,則默認使用'G'選項。它與'grep -G「p \ {2 \}」textfile'相同。 – 2011-05-06 20:05:47

+0

@empo是我現在明白了。請參閱下面的答案。 – nsfyn55 2011-05-10 15:47:27

回答

0

使用引號,您的完整正則表達式直接傳遞給grep。如果沒有引號,grep會將您的正則表達式視爲p{2}

編輯:

爲了澄清,不帶引號的斜線正在殼去除之前,你的正則表達式被傳遞到grep。

嘗試:

echo grep p\{2\} test.txt 

,你會看到你的輸出...

grep p{2} test.txt 

引號防止外殼逃逸字符他們得到給grep之前。你也可以逃避你的斜線,它會工作沒有引號 - grep p\\{2\\} test.txt

+0

如果沒有-e選項,grep不支持regex。我已經嘗試了很多方法,並且不知道爲什麼它以單向方式工作而不是其他方式 – nsfyn55 2011-05-06 19:27:30

+0

grep s {2} pom.xml不返回任何內容,但grep「s \ {2 \}」pom.xml返回所有單詞組件的實例。 grep s \ {2 \}也不會返回 – nsfyn55 2011-05-06 19:29:48

+1

等等,什麼? '-e'對於以'-'開頭的模式是一種方便(並且早於'--'約定)。 'grep'支持POSIX BREs(並且,作爲GNU擴展,ERE語法反斜槓);在POSIX BREs中定義'{}'需要反斜槓(但不在ERE中,這是GNU獲得其擴展的想法)。 – geekosaur 2011-05-06 19:41:18

1

沒有引號,shell將嘗試擴展選項。在你的情況下,大括號'{}'在shell中具有特殊含義,就像星號'*'擴展爲通配符。

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 

- 從其他外殼,附着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旗神祕尚未解決....

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\}" 

第一用途ERES(擴展正則表達式),第二個使用BREs裏面(基本正則表達式)在你的例子中,因爲你使用grep(當你支持BRE時不要使用-e開關),並且用引號括起來,所以「\ {」會被擴展爲一個特殊的BRE字符。

您二審不工作,因爲你只是在尋找文本字符串2 {P}不以你的文件存在

可以證明的grep通過嘗試擴大你的字符串作爲BRE:

grep "p\{2" 

的grep會抱怨

grep: Unmatched \{ 
0

第一種使用正則表達式裏grep圖案,然後pp

 
echo "apple" | grep 'p\{2\}' 

第二個字面上的裏grep模式,然後p{2}

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