【问题标题】:Finding files in a directory using Python wildcards but avoiding certain text使用 Python 通配符在目录中查找文件但避免使用某些文本
【发布时间】:2019-11-09 22:47:30
【问题描述】:

对不起,标题的火车残骸......不知道该怎么形容它。

我一次从某个目录提取一个类别的文件。类别是文件名的一部分,遵循非常特定的格式,但有一些问题让我的流程中断。

示例文件名:

.../Bike.txt

如果特定类别的源数据过多,系统将创建编号文件来处理溢出。在这种情况下,文件可能如下所示:

.../Bike_1.txt

.../Bike_2.txt

我需要获取特定类别的文件,无论它是“Bike.txt”还是“Bike_1.txt”。我想我可以使用通配符来查找匹配“Bike*.txt”的文件。问题是我可能还有一个名为“Bike_Helmet.txt”的文件,如果我目前正在查看自行车类别,我不想摄取该文件。

这是使用 Databricks 中的 PySpark 完成的。到目前为止,我一直使用 glob 库来处理这个问题,但我不确定它是否能满足我的需要。

总结一下,指定类别后,我想找到符合以下格式的文件:

.../[类别].txt

.../[类别]_[一个数字].txt

但我不想检索格式为 .../[category]_[non-numeric string].txt 的文件。

有没有办法一次性做到这一点,或者我必须先根据 .../[category].txt 然后 .../[category]_[0-9]* 摄取。 txt第二遍?

【问题讨论】:

    标签: python-3.x pyspark glob


    【解决方案1】:

    我认为您可以在 Pyspark 中使用 Python 来处理这个问题。

    假设您可以通过 glob 获取目标目录中所有文件的列表。 (我不确定是否是这种情况,或者您是否需要同时扫描文件并有条件地摄取。但为了第一个答案,我做出上述假设)。

    假设这会产生以下列表:

    file_list = [
        'Bike.txt',
        'Bike_1.txt',
        'Bike_2.txt',
        'Bike_49341.txt',
        'Bike_helmet.txt',
        'Bike_wheelie.txt',
        'Helmet.txt',
        'Helmet_1.txt',
    ]
    

    This SO answer 提供了一个很好的解决方案,用于确定字符串是否为数字:

    def is_number(n):
        try:
            float(n)   # Type-casting the string to `float`.
                       # If string is not a valid `float`, 
                       # it'll raise `ValueError` exception
        except ValueError:
            return False
        return True
    

    现在你有了一个文件名列表和一个判断字符串是否为数字的函数。使用它,我们可以获得有效文件名的列表。

    from pathlib import PurePath
    
    target_category = "bike"
    valid_files = []
    for file_name in file_list:
        file_stem = PurePath(file_name).stem
        file_split = file_stem.split("_")
        if file_split[0].lower() == target_category:
            if len(file_split) == 1:
                valid_files.append(file_name)
            else:
                if is_number(file_split[1]):
                    valid_files.append(file_name)
    

    产生:

    >>> valid_files
    ['Bike.txt', 'Bike_1.txt', 'Bike_2.txt', 'Bike_49341.txt']
    

    您现在可以返回并仅导入 valid_files 中的那些文件

    编辑:更改了答案,因此首先检查以确保类别正确。

    注意:PurePath(filename).stem 仅在文件具有单个(即.txt)而不是多个(即.tar.gz)后缀时有效。

    【讨论】:

      【解决方案2】:

      您可以使用pathlib(或较旧的glob,或简单地使用os.listdir())搜索所有以“Bike”开头的文件,然后使用regular expression 忽略无效结果。

      import pathlib
      import re
      
      def get_files(category):
          prog = re.compile(category + '(_\d+)?\.txt')
          return [file for file in pathlib.Path('..').glob(category + '*.txt') if prog.match(file.name)]
      
      
      bike_files = get_files('Bike')
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-05
        • 1970-01-01
        相关资源
        最近更新 更多