2013-05-01 39 views
2

如何在Python中讀取整個文件?我想我不過腳本工作它被稱爲如何在Python中讀取整個文件?在命令行中通用工作

  • script.py log.txt
  • script.py < log2.txt
  • python script.py < log2.txt
  • python -i script.py logs/yesterday.txt

你的想法。


我試圖

import fileinput 
from bs4 import BeautifulSoup 
f = fileinput.input() 
soup = BeautifulSoup(f.read()) 

,但我得到

Traceback (most recent call last): 
    File "visual-studio-extension-load-times.py", line 5, in <module> 
    soup = BeautifulSoup(f.read()) 
AttributeError: FileInput instance has no attribute 'read' 
+0

like'f = open(fileinput。輸入())'但有正確的異常處理和東西? – Aprillion 2013-05-01 15:47:49

+0

你想從標準輸入讀取而不是讀取參數,然後打開並讀取文件? – nacholibre 2013-05-01 15:50:12

+1

下面的答案處理閱讀文件名作爲命令行參數,但如果你還希望它強大的標誌像-i退房[optparse](http://docs.python.org/2/library/optparse.html) – ejrb 2013-05-01 15:54:23

回答

4

而不是使用fileinput的,直接打開該文件自己:

import sys 
try: 
    fileobj = open(sys.argv[1], 'r') 
except IndexError: 
    fileobj = sys.stdin 

with fileobj: 
    data = fileobj.read() 
+0

爲什麼不使用'argparse'? http://stackoverflow.com/a/16321831/748858 :-P – mgilson 2013-05-01 16:07:05

+0

@mgilson:因爲這很簡單嗎? – 2013-05-01 16:08:39

+0

@mgilson:'python -i'切換到交互模式,但是'sys.argv'仍然與其他變體相同。 – 2013-05-01 16:16:34

5
f = open('file.txt', 'r') 
data = f.read() 
f.close() 

進一步,打開命令行通過了一個文件,你可以這樣做: (也,此是一個更聰明的方式來打開文件,而不是f = open(...)你可以做with ...

import sys 
with open(sys.argv[1], 'r') as f: 
    data = f.read() 

原因with被打開的文件,一個更聰明的方法是,因爲你離開縮進with塊後,將程序自動關閉文件。 這意味着你不必「擔心」有關的文件被打開或遺忘長(可能會導致「許多開放的文件句柄」從你的OS)


然後sys.argv

sys.argv[1]將是你的python文件後命令行上的第一個參數。
sys.argv[0]將是您的腳本名稱。例如:

python myscript.py heeyooo將是:

  • sys.argv[0] == "myscript.py"
  • sys.argv[1] == "heeyooo" :)

再有就是各種模塊的處理文件時,這將是有趣的你。
首先,os.path是一個不錯的開始,因爲您最有可能希望儘可能多地跨平臺,這使您可以選擇在Linux上將\轉換爲/,反之亦然。 幾個不錯的的是:

  • os.path.abspath則
  • os.path.isfile
  • os.path中。ISDIR

你也有os.getcwd()這可能是不錯的:)

2
script.py log.txt 
script.py < log2.txt 

這兩個都是非常不同調用你的劇本!首先,shell將文件名log.txt傳遞給腳本;在第二種情況下,shell將腳本的標準輸入連接到文件log2.txt,腳本從未真正看到文件名。

可能在同一個腳本中處理這兩個。一種方法是如果沒有文件在命令行上傳遞,則從標準輸入中讀取。另一種方法是從標準輸入讀取,如果它不是一個終端,然後讀取命令行上列出的文件,如果有的話(我喜歡fileinput這個,如果你有興趣閱讀的行,但不關心什麼文件他們來自)。如果標準輸入是終端,您可以使用sys.stdin.isatty()返回True。因此,像這樣:

import sys, fileinput 
if not sys.stdin.isatty(): 
    for line in sys.stdin: 
     process(line) 
for line in fileinput.input(): 
    process(line) 

但是,如果你正在尋找處理每個文件作爲一個整體,因爲它的出現,那麼fileinput不會做。相反,單獨讀取命令行中的每個文件名,讀取指定的文件,並對其進行處理:

import sys 
if not sys.stdin.isatty(): 
    stdin = sys.stdin.read() 
    if stdin: 
     process(stdin) 
for filename in sys.argv[1:]: 
    with open(filename) as f: 
     process(f.read()) 

現在對於這些調用:

python script.py < log2.txt 
python -i script.py logs/yesterday.txt 

這些都是一樣的,就好像你剛直接調用script.py就足夠了,所以你不需要特別處理它們。使用-i選項輸入間接(<)可能會導致一些意外的行爲,但我沒有嘗試過(並且無論如何都沒有辦法解決它)。

2

argparse救援!:

>>> import sys 
>>> import argparse 
>>> parser = argparse.ArgumentParser() 
>>> parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), 
...      default=sys.stdin) 
>>> args = parser.parse_args() 
>>> file_data = args.infile.read() 
0

去與此。

import sys 
from bs4 import BeautifulSoup 
f = open(sys.argv[1]) if sys.argv[1:] else sys.stdin 
soup = BeautifulSoup(f) 
0

它聽起來並不像你真正擺在首位想fileinput,因爲你不是要連接多個文件,辦理名稱-爲「把標準輸入這裏」等

但是,如果你想fileinput,而不是試圖重現它的所有行爲,只是把它包起來。

您想將所有輸入讀入一個字符串,但它提供的是一次只能給出一行或一個文件的函數。所以,你可以做什麼?將它們加在一起:

soup = BeautifulSoup(''.join(f)) 

就是這樣。

+0

我試過'''.join(f)'它打印了無數的怪異文本。也許是一個unicode問題? – 2013-05-01 17:02:24

+1

「它打印了無數的奇怪文字」是什麼意思?只是調用'join'可能會導致_anything_被打印出來。如果不知道實際的代碼以及運行它的數據,以及預期的和實際的輸出,就很難猜測出現了什麼問題。 – abarnert 2013-05-01 17:53:32

相關問題