【问题标题】:How to use os.walk to only list text files如何使用 os.walk 仅列出文本文件
【发布时间】:2016-05-31 13:32:00
【问题描述】:

This 问题在解决隐藏文件类型方面类似。我正在努力解决类似的问题,因为我只需要处理包含具有许多不同文件类型(图片、文本、音乐)的文件夹中的文件的文本。我正在使用 os.walk 列出所有内容,包括没有类似扩展名的图标文件的文件。我正在使用 linux,并且会满足于仅过滤 txt 文件。一种方法是检查文件扩展名,this 帖子很好地解释了它是如何完成的。

但这仍然会留下标签错误的文件或没有扩展名的文件。有一些十六进制值可以唯一标识称为幻数或文件签名的文件类型。 herehere 不幸的是,文本文件不存在幻数 (see here)。

我想出的一个策略是通过字典查找来解析第一组字符以确保它们是单词(我只处理英文文本)然后只进行全文处理,如果是的话是的。这种方法似乎相当繁重和昂贵(为每个文件做一堆字典查找)。另一种方法是简单地查找在数据文件中不太可能出现但在文本文件中常见的单词“the”。但是误报会导致我丢失要处理的文本文件。我尝试向谷歌询问没有“the”这个词的最长文本,但没有运气。

我不知道这是否是此类问题的合适论坛 - 这几乎是 AI 问题,而不是计算机科学/编码问题。它不像乱码检测那么难。这些文本可能在语义上或句法上不正确——它们可能只是像储藏室清单这样的词,但也可能是散文和诗歌。我只是不想处理可能是字节码、源代码或不是英文单词的字母数字字符集合的文件。

【问题讨论】:

  • find . -type f -exec grep -Iq . {} \; -and -print 来自Here
  • txt文件是指名称以.txt结尾的文件吗?否则你的问题没有多大意义。
  • 在这种情况下定义“文本”。只有ascii的文件? UTF-8? HTML?请更清楚。
  • file 命令可以很好地告诉您它是什么类型的文件。

标签: python text-processing


【解决方案1】:

您可以使用 Python 的 mimetypes 库来检查文件是否为纯文本文件。

import os
import mimetypes

for dirpath, dirnames, filenames in os.walk('/path/to/directory'):
    for filename in filenames:
        if mimetypes.guess_type(filename)[0] == 'text/plain':
            print(os.path.join(dirpath, filename))

更新:由于mimetypes库使用文件扩展名来确定文件的类型,所以它不是很可靠,特别是因为您提到某些文件标记错误或没有扩展名。

对于这些情况,您可以使用magic 库(不幸的是,它不在标准库中)。

import os
import magic

mime = magic.Magic(mime=True)
for dirpath, dirnames, filenames in os.walk('/path/to/directory'):
    for filename in filenames:
        fullpath = os.path.join(dirpath, filename)
        if mime.from_file(fullpath) == 'text/plain':
            print(fullpath)

更新 2:上述解决方案不会捕获您认为是“纯文本”的文件(例如 XML 文件、源文件等)。以下解决方案应该适用于这些情况:

import os
import magic

for dirpath, dirnames, filenames in os.walk('/path/to/directory'):
    for filename in filenames:
        fullpath = os.path.join(dirpath, filename)
        if 'text' in magic.from_file(fullpath):
            print(fullpath)

如果这些对你有用,请告诉我。

【讨论】:

  • 请注意guess_type中的猜测。
【解决方案2】:

一个很好的启发式方法是在文件的开头查找空字节。文本文件通常没有它们,而二进制文件通常有很多。下面检查前 1K 字节是否不包含空值。您当然可以调整要读取的文件的大小:

#!python3
import os

def textfiles(root):
    for path,dirs,files in os.walk(root):
        for file in files:
            fullname = os.path.join(path,file)
            with open(fullname,'rb') as f:
                data = f.read(1024)
            if not 0 in data:
                yield fullname

for file in textfiles('.'):
    print(file)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-18
    • 1970-01-01
    • 1970-01-01
    • 2019-02-05
    • 1970-01-01
    • 2016-10-17
    • 1970-01-01
    • 2014-12-26
    相关资源
    最近更新 更多