2013-07-23 17 views
3

我想逐行處理文件。不過,我需要排序它,我通常通過管道排序:管道輸出Linux的最佳方式排序

sort --key=1,2 data |./script.py. 

什麼是最好的從Python內部調用排序?在線搜索我看到subprocesssh模塊可能是可能的嗎?我不想將這個文件讀入內存,並在python中排序,因爲數據非常大。

+3

供參考:排序必須讀取內存中的文件 – SheetJS

+2

不完全。 Linux的排序非常巧妙,可以使用外部存儲器排序算法對大量文件進行排序,使其大於RAM。參見http://stackoverflow.com/questions/930044/how-could-the-unix-sort-command-sort-a-very-large-file。 – phoenix

+0

也許排序,也許它不需要將文件讀入內存,但是再次,爲什麼Python? (如果'sort'可以很聰明,那麼Python也可以。) – kojiro

回答

3

它很容易。使用subprocess.Popen運行排序並讀取其stdout以獲取數據。

import subprocess 
myfile = 'data' 
sort = subprocess.Popen(['sort', '--key=1,2', myfile], 
    stdout=subprocess.PIPE) 
for line in sort.stdout: 
    your_code_here 
sort.wait() 
assert sort.returncode == 0, 'sort failed' 
+0

sort.wait()是做什麼的?看起來sort在任何情況下都必須先完成。 – phoenix

+0

for循環讀取進程stdout,直到進程關閉它(通常在進程退出但進程是空閒的,儘早關閉,如果它想的話)。 wait()調用等待進程退出並獲取其返回碼。這在Linux上非常重要,因爲它可以從系統進程表中刪除殭屍進程。 – tdelaney

+0

非常感謝。 – phoenix

0

我相信那種會讀取內存中的所有數據,所以我不相信你會贏得任何東西,但你可以在subprocess使用shell=True並使用管道

>>> subprocess.check_output("ls", shell = True) 
'1\na\na.cpp\nA.java\na.php\nerase_no_module.cpp\nerase_no_module.cpp~\nWeatherSTADFork.cpp\n' 
>>> subprocess.check_output("ls | grep j", shell = True) 
'A.java\n' 

警告
如果與不可信輸入結合使用,調用shell = True的系統shell可能會帶來安全隱患。有關詳細信息,請參閱常用參數下的警告。

+0

謝謝。排序不會將整個文件讀入內存。請參閱http://stackoverflow.com/questions/930044/how-could-the-unix-sort-command-sor t-a-large-large-file。 。 – phoenix

0

我認爲this page會回答你的問題

答案我願意,從@Eli Courtwright是(所有報價逐字):

下面是調用外部程序的優勢及方式的概述和每個的缺點:

  1. os.system("some_command with args")將命令和參數傳遞到您的系統的shell。這很好,因爲你可以用這種方式一次運行多個命令,並設置管道和輸入/輸出重定向。例如,
    os.system("some_command < input_file | another_command > output_file")
    然而,儘管這很方便,你必須手動處理的外殼字符,如空格等。另一方面逸出,這也可以讓你運行的是簡單的shell命令,並沒有實際的命令外部程序。
    http://docs.python.org/lib/os-process.html

  2. stream = os.popen("some_command with args")會做同樣的事情,不同的是它給你一個類文件對象,您可以使用訪問標準輸入/輸出該進程os.system。還有另外3種不同的popen,它們處理I/O的方式略有不同。如果你把所有東西都作爲一個字符串傳遞,那麼你的命令被傳遞給shell;如果你將它們作爲列表傳遞給你,那麼你不需要擔心逃脫任何事情。
    http://docs.python.org/lib/os-newstreams.html

  3. Popensubprocess模塊。這是爲了取代os.popen,但由於其如此全面而略微複雜一些。例如,你會說
    print Popen("echo Hello World", stdout=PIPE, shell=True).stdout.read()
    而不是
    print os.popen("echo Hello World").read()
    ,但它是好的,有所有的選項中有一個統一的類,而不是4種不同的popen功能。
    http://docs.python.org/lib/node528.html

  4. subprocess模塊call功能。這基本上和Popen類一樣,並且採用了所有相同的參數,但它只是等到命令完成並給出返回碼。例如:
    return_code = call("echo Hello World", shell=True)
    http://docs.python.org/lib/node529.html

  5. os模塊還擁有了這一切,你不得不在C程序叉/ EXEC /產卵功能,但我不建議直接使用它們。

subprocess模塊可能應該是你使用的。

+0

謝謝,但我認爲shell = True已被棄用。 – phoenix

+0

你可能比我更瞭解 - 我仍然是Python初學者。 – liang