我有一个20个文件名的列表,比如['file1.txt', 'file2.txt',…]。我想写一个Python脚本将这些文件连接到一个新文件中。我可以通过f = open(…)打开每个文件,通过调用f.r edline()逐行读取,并将每行写入新文件。这对我来说似乎不是很“优雅”,尤其是我必须一行一行地读/写的部分。

在Python中是否有更“优雅”的方式来做到这一点?


当前回答

如果目录中有很多文件,那么glob2可能是生成文件名列表的更好选择,而不是手工编写它们。

import glob2

filenames = glob2.glob('*.txt')  # list of all .txt files in the directory

with open('outfile.txt', 'w') as f:
    for file in filenames:
        with open(file) as infile:
            f.write(infile.read()+'\n')

其他回答

outfile.write(infile.read()) # time: 2.1085190773010254s
shutil.copyfileobj(fd, wfd, 1024*1024*10) # time: 0.60599684715271s

一个简单的基准测试表明,shutil的性能更好。

@inspectorG4dget答案的替代答案(到2016年3月29日为止的最佳答案)。我测试了3个436MB的文件。

@inspectorG4dget答案:162秒

解决方案:125秒

from subprocess import Popen
filenames = ['file1.txt', 'file2.txt', 'file3.txt']
fbatch = open('batch.bat','w')
str ="type "
for f in filenames:
    str+= f + " "
fbatch.write(str + " > file4results.txt")
fbatch.close()
p = Popen("batch.bat", cwd=r"Drive:\Path\to\folder")
stdout, stderr = p.communicate()

其思想是创建一个批处理文件并执行它,利用“旧的好技术”。它是半python,但运行速度更快。适用于windows。

这样就行了

对于大文件:

filenames = ['file1.txt', 'file2.txt', ...]
with open('path/to/output/file', 'w') as outfile:
    for fname in filenames:
        with open(fname) as infile:
            for line in infile:
                outfile.write(line)

对于小文件:

filenames = ['file1.txt', 'file2.txt', ...]
with open('path/to/output/file', 'w') as outfile:
    for fname in filenames:
        with open(fname) as infile:
            outfile.write(infile.read())

我还想到了另一个有趣的问题:

filenames = ['file1.txt', 'file2.txt', ...]
with open('path/to/output/file', 'w') as outfile:
    for line in itertools.chain.from_iterable(itertools.imap(open, filnames)):
        outfile.write(line)

遗憾的是,最后一个方法留下了一些打开的文件描述符,无论如何GC都应该处理这些描述符。我只是觉得很有趣

def concatFiles():
    path = 'input/'
    files = os.listdir(path)
    for idx, infile in enumerate(files):
        print ("File #" + str(idx) + "  " + infile)
    concat = ''.join([open(path + f).read() for f in files])
    with open("output_concatFile.txt", "w") as fo:
        fo.write(path + concat)

if __name__ == "__main__":
    concatFiles()

UNIX命令有什么问题?(假设你不是在Windows上工作):

Ls | xargs cat | tee output.txt完成这项工作(如果你想要,你可以从python用subprocess调用它)