2012-03-03 117 views
4

平臺稱爲:視窗grep命令從蟒

grep的:http://gnuwin32.sourceforge.net/packages/grep.htm

的Python:用於執行命令2.7.2

Windows命令提示。

我正在尋找一個文件中的以下模式"2345$"。是 該文件的內容如下:

abcd 2345 

2345 

abcd 2345$ 

grep "2345$" file.txt

grep的返回2線(第一和第二)成功。

當我嘗試通過python運行上述命令時,我看不到任何輸出。 Python代碼片斷如下:

temp = open('file.txt', "r+") 
grep_cmd = [] 
grep_cmd.extend([grep, '"2345$"' ,temp.name]) 
print grep_cmd 
p = subprocess.Popen(grep_cmd, 
     stdout=subprocess.PIPE, 
     stderr=subprocess.PIPE) 
stdoutdata = p.communicate()[0] 
print stdoutdata 

如果我在python腳本有

grep_cmd.extend([grep, '2345$' ,temp.name]) 

,我得到正確的答案。

的問題是,爲什麼從蟒蛇執行與"

grep_cmd.extend([grep, '"2345$"' ,temp.name]) 

grep命令失敗。不是python應該按照原樣執行 命令。

謝謝 Gudge。

+2

對不起,沒有直接回答你的問題,但有沒有什麼原因你不想在Python中手動「grep」文件?通過使用,例如're'?這將是更少的線... – tomasz 2012-03-03 01:08:12

+0

我明白我可以做一個re.search。這是通過python執行命令的具體要求。 – gudge 2012-03-03 01:25:10

+1

好的,公平的@gudge。不要誤解我的意思,只是想確保你知道你在做什麼:) – tomasz 2012-03-03 01:26:54

回答

4

不要在你的模式中加雙引號。只需要在命令行中引用shell元字符。當從python調用一個程序時,你不需要這個。

你也不需要打開該文件自己 - grep的將這樣做:

grep_cmd.extend([grep, '2345$', 'file.txt']) 

要了解雙引號不被需要,造成你的命令失敗的原因,你需要了解雙引號的用途以及它們如何處理。

shell使用雙引號來防止某些shell元字符的特殊處理。 Shell元字符是shell特別處理的那些字符,並且不會直接傳遞給它執行的程序。最常用的shell元字符是「空格」。 shell在空間邊界上分割一個命令來構建一個參數向量來執行一個程序。如果您想在參數中包含空格,則必須以某種方式引用它(單引號或雙引號,反斜槓等)。另一個是美元符號($),用於表示可變擴展。

當您在沒有涉及shell的情況下執行程序時,所有關於引用和shell元字符的規則都不相關。在python中,你自己構建參數向量,所以相關的引用規則是python引用規則(例如,在雙引號字符串中包含雙引號,在雙引號前加一個反斜槓 - 反斜槓不會在最後串)。完成構造時,參數向量的每個元素中的字符都是將傳遞給正在執行的程序的文字字符。

grep不會將雙引號視爲特殊字符,所以如果grep在其搜索模式中使用雙引號,它會嘗試從其輸入中匹配雙引號。

我原來對shell=True的回答是不正確的 - 首先我沒注意到你最初指定的是shell=True,其次我是從Unix/Linux實現的角度來看的,而不是Windows。

蟒蛇子模塊頁有這樣說shell=True和Windows:

在Windows上:在POPEN類使用的CreateProcess()來執行的孩童方案,該方案對字符串進行操作。如果參數是一個序列,它將按照Converting an argument sequence to a string on Windows中所述的方式轉換爲字符串。

在Windows上將參數序列轉換爲字符串的鏈接部分對我來說沒有意義。首先,一個字符串是一個序列,因此是一個列表,但經常使用的參數部分中說,這大約參數:

ARGS所需的所有來電,應該是一個字符串,或者程序參數的順序。提供一系列參數通常是首選,因爲它允許模塊處理任何所需的參數轉義和引用(例如,允許文件名中的空格)。

這與Python文檔中描述的轉換過程相矛盾,並且考慮到您觀察到的行爲,我會說文檔是錯誤的,只適用於參數字符串,而不是參數向量。我無法驗證這一點,因爲我沒有Windows或Python的源代碼。

我懷疑,如果你打電話subprocess.Popen這樣的:

p = subprocess.Popen(grep + ' "2345$" file.txt', stdout=..., shell_True) 

,你可能會發現,雙引號被剝離出來作爲記錄的參數轉換的一部分。

+0

它沒有雙引號。但是它不應該與雙引號一起工作。如果我沒有錯,Python應該選擇數組的內容。如果是這種情況,那麼通過python執行的grep命令(使用雙引號)應該返回兩行。 – gudge 2012-03-03 01:40:31

+1

@grudge:當你在雙引號內加雙引號時,雙引號成爲模式的一部分。顯然,你的文件沒有引號,因此它不匹配。請記住,當您從命令行調用grep時,shell會在grep看到它們之前刪除引號。 – 2012-03-03 02:39:46

+0

gudge:我已經更新了我的答案,以擴展參數的處理方式,並評論我認爲可能直接導致混淆的錯誤。 – camh 2012-03-03 23:12:49