很抱歉标题的残骸...不知道该怎么写。
我一次从某个目录中的一个目录中提取文件。类别是文件名的一部分,遵循一种非常特定的格式,但是有一些问题使我的工作陷入困境。
示例文件名:
... / Bike.txt
如果特定类别的源数据过多,则系统将创建编号文件来处理溢出。在这种情况下,文件可能看起来像这样:
... / Bike_1.txt
... / Bike_2.txt
无论是“ Bike.txt”还是“ Bike_1.txt”,我都需要获取特定类别的文件。我想我可以使用通配符来查找与“ Bike * .txt”匹配的文件。问题是我可能还有一个名为“ Bike_Helmet.txt”的文件,如果我当前正在查看自行车类别,则我不想提取该文件。
这是通过使用Databricks中的PySpark完成的。到目前为止,我一直使用glob库来处理此问题,但是我不确定它是否可以满足我的需要。
总而言之,在指定类别之后,我要查找与以下格式匹配的文件:
... / [category] .txt
... / [类别] _ [数字] .txt
但是我不想检索格式为... / [类别] _ [非数字字符串] .txt的文件。
有没有办法一次性完成此操作,还是我必须首先基于... / [category] .txt提取,然后再基于... / [category] _ [0-9] *提取。 txt第二次?
答案 0 :(得分:0)
我认为您可以在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
)后才有效。
答案 1 :(得分:0)
您可以使用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')