我需要遍历一个文件夹,并找到文件名相同(扩展名除外)的每个实例,然后将每个文件名压缩(最好使用tarfile)到一个文件中.
因此,我有5个文件名为:“ example1”,每个文件具有不同的文件扩展名.我需要将它们拉在一起并将其输出为“ example1.tar”或类似内容.
通过简单的for循环,这将很容易,例如:
tar = tarfile.open(‘example1.tar’,”w”)
for output in glob (‘example1*’):
tar.add(output)
tar.close()
但是,有300个“示例”文件,为了使这项工作有效,我需要遍历每个文件及其关联的5个文件.这是我的头.任何建议,不胜感激.
解决方法:
您描述的模式可以概括为MapReduce.我在网上发现了a simple implementation的MapReduce,从中可以找到一个更简单的版本:
def map_reduce(data, mapper, reducer):
d = {}
for elem in data:
key, value = mapper(elem)
d.setdefault(key, []).append(value)
for key, grp in d.items():
d[key] = reducer(key, grp)
return d
您想按文件名对所有文件进行分组,但不带扩展名,可以从os.path.splitext(fname)[0]中获得.然后,您想使用tarfile模块在每个组中制作一个tarball.在代码中,即:
import os
import tarfile
def make_tar(basename, files):
tar = tarfile.open(basename + '.tar', 'w')
for f in files:
tar.add(f)
tar.close()
map_reduce(os.listdir('.'),
lambda x: (os.path.splitext(x)[0], x),
make_tar)
编辑:如果要以不同的方式对文件进行分组,则只需将第二个参数修改为map_reduce.上面的代码对表达式os.path.splitext(x)[0]具有相同值的文件进行分组.因此,要按基本文件名分组并去除所有扩展名,可以将该表达式替换为strip_all_ext(x)并添加:
def strip_all_ext(path):
head, tail = os.path.split(path)
basename = tail.split(os.extsep)[0]
return os.path.join(head, basename)