2013-05-01 23 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

相关问题