【问题标题】:Combine a folder of text files into a CSV with each content in a cell将一个文本文件文件夹合并为一个 CSV,其中每个内容都在一个单元格中
【发布时间】:2017-06-14 06:24:18
【问题描述】:

我有一个包含数千个 .txt 文件的文件夹。我想根据以下模型将它们组合成一个大的 .csv:

我发现了一个 R 脚本应该完成这项工作 (https://gist.github.com/benmarwick/9265414),但它显​​示了这个错误。

Error in read.table(file = file, header = header, sep = sep, quote = quote,  : duplicate 'row.names' are not allowed 

我不明白我的错误是什么。

不管怎样,我很确定没有 R 也有办法做到这一点。如果你知道一个非常优雅和简单的方法,那将不胜感激(并且对像我这样的很多人有用)

PRECISION : 文本文件是法语的,所以不是 ASCII。这是一个示例:https://www.dropbox.com/s/rj4df94hqisod5z/Texts.zip?dl=0

【问题讨论】:

  • 如果你对 Python 非常熟悉,那么使用osmodule 中的os.walk 编写 Python 脚本来查看目录的内容应该不会太难, 和 csv module 创建 csv。
  • 当然,Python 中肯定有很酷的解决方案。我可以考虑一下,但这需要我几个小时(我不够熟练)而且我害怕重新发明轮子。这是很多人肯定遇到过的问题。奇怪的是,我在 Google 中找不到现成的解决方案。 ://
  • 您希望文本文件的行在没有换行符的情况下简单连接吗?
  • 换行符是有用的信息,但对我来说不是很重要。

标签: python r csv


【解决方案1】:

以下 python 脚本适用于我(其中path_of_directory 替换为您的文件所在目录的路径,output_file.csv 是您要创建/覆盖的文件的路径):

#! /usr/bin/python

import os
import csv

dirpath = 'path_of_directory'
output = 'output_file.csv'
with open(output, 'w') as outfile:
    csvout = csv.writer(outfile)
    csvout.writerow(['FileName', 'Content'])

    files = os.listdir(dirpath)

    for filename in files:
        with open(dirpath + '/' + filename) as afile:
            csvout.writerow([filename, afile.read()])
            afile.close()

    outfile.close()

请注意,这假定目录中的所有内容都是一个文件。

【讨论】:

  • 通常的 unicode 错误(文本是法语...),但我要重试:SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3 : 截断 \UXXXXXXXX 转义(,第 7 行)文件“”,第 7 行 dirpath = 'C:\Users\ettor\Desktop\Nouveau dossier' ^ SyntaxError:(unicode 错误)“unicodeescape”编解码器无法解码位置 2-3 中的字节:截断 \UXXXXXXXX 转义
  • 如果你在'C:\Users\ettor\Desktop\Nouveau dossier'前面加上一个r(这样它就变成了r'C:\Users\ettor\Desktop\Nouveau dossier'),应该可以解决这个问题(见stackoverflow.com/questions/1347791/…)。如果您的文件不是全 ASCII(即包含 Unicode),我不知道这是否会成为问题。
  • 即使使用我发布的简短示例也不起作用:UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 1792: character maps to 我找到了这些关于 unicode 的故事极好的。孩子可以将每个文本文件的内容复制并粘贴到 CSV 中的一个单元格中,但自动化这件事是一件令人头疼的事情。
  • 好吧,至少它现在似乎在实际的 Unicode 上失败了,因为转义字符,没有将您的文件路径解释为包含 Unicode。我编写的脚本会遍历大量文件并将其部分内容转换为不同的格式(XML、JSON、CSV),而 Unicode 总是让人头疼。我会尽量记住我是如何解决的。
【解决方案2】:

可以使用 pathlib 稍微更紧凑地编写。

>>> import os
>>> os.chdir('c:/scratch/folder to process')
>>> from pathlib import Path
>>> with open('big.csv', 'w') as out_file:
...     csv_out = csv.writer(out_file)
...     csv_out.writerow(['FileName', 'Content'])
...     for fileName in Path('.').glob('*.txt'):
...         csv_out.writerow([str(fileName),open(str(fileName.absolute())).read().strip()])

此 glob 生成的项目提供对完整路径名和文件名的访问,因此不需要连接。

编辑:我检查了其中一个文本文件,发现阻碍处理的字符之一看起来像“fi”,但实际上这两个字符一起作为一个字符。鉴于此 csv 可能的实际用途,我建议进行以下处理,该处理忽略像那个奇怪的字符。我去掉了尾线,因为我怀疑这会使 csv 处理更加复杂,并且可能成为另一个问题的主题。

import csv
from pathlib import Path

with open('big.csv', 'w', encoding='Latin-1') as out_file:
    csv_out = csv.writer(out_file)
    csv_out.writerow(['FileName', 'Content'])
    for fileName in Path('.').glob('*.txt'):
        lines = [ ]
        with open(str(fileName.absolute()),'rb') as one_text:
            for line in one_text.readlines():
                lines.append(line.decode(encoding='Latin-1',errors='ignore').strip())
        csv_out.writerow([str(fileName),' '.join(lines)])

【讨论】:

  • Il fonctionne avec le français.
  • 谢谢比尔,但我还有另一个 Unicode 错误:SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape 在投票选出最佳解决方案之前,也许我清理文件会更明智。我没想到将法语文本复制到单元格中会如此困难。
  • 你能把那个文本文件贴在我们可以访问的地方吗?或者,如果它很大,最好发布包含生成错误条件的字节的部分。
  • 当然。我在问题本身中添加了一个示例。它基本上是从 pdf 文档中提取的文本集合。
  • 谢谢,我正在看。
【解决方案3】:

如果您的 txt 文件不是表格格式,您最好使用readLines()。这是在基础R 中执行此操作的一种方法:

setwd("~/your/file/path/to/txt_files_dir") 
txt_files <- list.files()
list_of_reads <- lapply(txt_files, readLines)
df_of_reads <- data.frame(file_name = txt_files, contents = do.call(rbind, list_of_reads))
write.csv(df_of_reads, "one_big_CSV.csv", row.names = F)

【讨论】:

  • 新创建的 data.frame 有问题:is.data.frame(x) 中的错误:找不到对象 'df_of_reads' 我必须更改语言环境才能得到英文错误,但是我是可以理解的:data.frame 中的错误(file_name = txt_files,contents = do.call(rbind,list_of_reads)):les arguments impliquent des nomres de lignes différents : 41, 40 另外:警告消息:在(函数( ..., deparse.level = 1) : 结果的列数不是向量长度的倍数 (arg 1)
  • 表格?不,对不起,也许我不清楚。我所有的 .txt 都是纯文本。这是 list_of_reads 的示例: [42] " '~1?'::\"~ .• ~\"" [43] " ~" [44] " La présente attestation ne vaut pasrelevé de注意。”
  • 那些嵌套的双引号会给你带来麻烦,也许是用gsub()删除它们
  • 如果你可以用单引号替换内部双引号,它会起作用,就像这样list("'~1?'::\'~ .• &lt;/~\'", " ~" )
  • Unicode 字符很痛苦......我明天早上会休息一下再试一次,不要把这个问题变成聊天。无论如何,谢谢你的一切!
猜你喜欢
  • 2020-09-05
  • 2021-05-27
  • 2017-08-17
  • 1970-01-01
  • 2019-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多