【问题标题】:How to merge a folder full of .txt files in a new .txt file preserving the encoding?如何将一个充满 .txt 文件的文件夹合并到一个保留编码的新 .txt 文件中?
【发布时间】:2014-12-18 13:57:23
【问题描述】:

我有一个文件夹,里面有很多非常大的 .txt 文件,它们看起来像这样:

File1:

eta eta NCFS000 1
lavadora lavador AQ0FS0 0.585262
es ser VSIP3S0 1
muy muy RG 1
buena bueno AQ0FS0 1


File2:
eta eta NCFS000 1
lavadora lavador AQ0FS0 0.585262
es ser VSIP3S0 1
muy muy RG 1
buena bueno AQ0FS0 1

File3:
eta eta NCFS000 1
lavadora lavador AQ0FS0 0.585262
es ser VSIP3S0 1
muy muy RG 1
buena bueno AQ0FS0 1
.
.
.
FileN
eta eta NCFS000 1
lavadora lavador AQ0FS0 0.585262
es ser VSIP3S0 1
muy muy RG 1
buena bueno AQ0FS0 1

谁能帮我用另一种方法来完成这项任务?,另一个问题是编码,文件是西班牙语,我想保留标点符号,比如重音符号之类的东西。我想在 new_file 中从 File1 合并到 FileN,即:

新文件:

eta eta NCFS000 1
lavadora lavador AQ0FS0 0.585262
es ser VSIP3S0 1
muy muy RG 1
buena bueno AQ0FS0 1
eta eta NCFS000 1
lavadora lavador AQ0FS0 0.585262
es ser VSIP3S0 1
muy muy RG 1
buena bueno AQ0FS0 1
eta eta NCFS000 1
lavadora lavador AQ0FS0 0.585262
es ser VSIP3S0 1
muy muy RG 1
buena bueno AQ0FS0 1
eta eta NCFS000 1
lavadora lavador AQ0FS0 0.585262
es ser VSIP3S0 1
muy muy RG 1
buena bueno AQ0FS0 1

这是我尝试过的:

import os


def concatFiles():
    path = '/Users/user/Desktop/OpinionsTAG_txt\'
    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()

output_contacFile.txt 有编码问题,我想保留重音符号和西班牙语符号,例如一些单词如下所示:

est√° estar VAIP3S0 

正确的输出应该是这样的:

está estar VAIP3S0

【问题讨论】:

  • 如果我理解正确,您可以在不接触 Python 的情况下将其作为单线执行:cat folder/full/of/etc/* > output_concateFile.txt
  • 不管怎样,你的尝试有什么错误
  • 我有这个例外:文件 #2311 Teka_TK2_1280__Opinion_2039705.html.txt concat = ''.join([open(path + f).read() for f in files]) 文件 #2312 Teka_TK2_1280__Opinion_2085252。 html.txt IOError: [Errno 2] 没有这样的文件或目录:'/Users/user/Desktop/OpinionsTAG_txt.DS_Store'
  • concat = ''.join([open(os.path.join(path , f)).read() for f in files]) 或者如果你真的不想使用 os.path.join 使用 path +"/"+ f
  • 错误似乎很明显。存在的文件是/Users/user/Desktop/OpinionsTAG_txt.DS_Store,没有这样的文件,但是有一个名为/Users/user/Desktop/OpinionsTAG_txt/.DS_Store的文件,所以你错过了一个/

标签: python string encoding io


【解决方案1】:

Zeroth,请注意,整个程序可以在没有 Python 的情况下完成,作为 shell 上的单行代码:cat /Users/user/Desktop/OpinionsTAG_txt/* > output_concatFile.txt

首先,要解决您的问题,正如 Joran Beasley 解释的那样,您刚刚忘记了目录路径和文件名之间的 /。而像这样的错误正是你想要使用os.path 而不是像哑字符串那样操作路径的原因。

接下来,与其在写任何东西之前将所有文件读入内存,不如一个一个地读取它们?

更好的是,不是一次读取整个文件,而是一次读取一个缓冲区;这样,如果您不小心将一个 36GB 的文件放到该目录中,您就不会尝试将整个文件读入内存并将您的计算机投入交换地狱。 copyfileobj 函数会自动为您执行此操作(尽管循环 iter(f.read(8192), b'') 也可以正常工作)。

此外,尝试打开可能数千个文件而不关闭其中任何一个可能不是一个好主意。

如果您想完全保留的内容,特别是如果这是 Python 3.x,您可能需要二进制模式。 (您可以改为使用正确的编码以 Unicode 文本模式打开文件 - 您看到的特定 mojibake 是由将 UTF-8 文本视为 MacRoman 引起的,它应该告诉您如何修复它。但是为什么要让事情变得困难呢?只需将字节复制为字节。)

最后,如果您需要保证文件按ls 显示的顺序显示……好吧,Python 不保证;事实上,listdir 明确表示“列表是任意顺序的”。但ls 保证按字典顺序排列,这与 Python 用于排序字符串的默认顺序相同。 (实际上,listdir 几乎总是会为您提供本机目录顺序,这通常是按字典顺序排列的,因此您可能不需要这个。但您不应该相信这一点。)

所以:

def concatFiles():
    path = '/Users/user/Desktop/OpinionsTAG_txt'
    files = os.listdir(path)
    with open("output_concatFile.txt", "wb") as fo:
        for f in sorted(files):
            with open(os.path.join(path, f), "rb") as fi:
                shutil.copyfileobj(fi, fo)

【讨论】:

  • 还是一样:r√°pido r√°pido
  • @samsmith:你如何看待这些文件?因为如果你有一些 UTF-8 文本文件,并且你以二进制模式连接它们,结果将是一个 UTF-8 文本文件。如果您随后将生成的文件视为 MacRoman 文本查看,它将被 mojibaked,但如果您将原始文件视为 MacRoman,情况也是如此。
  • 我不知道,我怎么知道 .txt 文件是什么格式的?
  • @samsmith:嗯,这是个大问题:文本文件不知道它们的编码是什么,因为它们只有编码文本。因此,这些信息必须来自其他地方。这就是为什么 Python 中的 str.decode 需要一个 encoding 参数,为什么 HTTP 的 Content-Type 标头有一个 encoding 属性等等。但再说一遍:你如何查看这些文件? cat 在终端?文本编辑?其他一些程序或应用程序?
【解决方案2】:

您可以在读取时写入,而不是先将所有文件读入内存,只需在遍历每个文件时写入输出文件即可:

def concatFiles():
    path = '/Users/user/Desktop/OpinionsTAG_txt'
    files = os.listdir(path)
    with open("output_concatFile.txt", "w") as fo: 
        for infile in files:
            with open(os.path.join(path, infile)) as fin:
                for line in fin:
                    fo.write(line)

【讨论】:

    【解决方案3】:

    如果您出于某种原因需要 Python 解决方案,可以在 Python 中实现 cat

    #!/usr/bin/env python2
    import fileinput
    
    for line in fileinput.input():
        print line,
    

    将其保存到 cat.py 并将所有 .txt 文件合并到一个文件夹中,运行:

    $ python -mcat /Users/you/Desktop/OpinionsTAG_txt/*.txt > output_concatFile.txt
    

    这里是cat.py for Python 3

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-11
      • 1970-01-01
      • 2014-02-24
      • 1970-01-01
      • 2015-02-06
      • 1970-01-01
      相关资源
      最近更新 更多