我需要遍历一个文件夹,找到文件名相同的每个实例(扩展名除外),然后将每个文件压缩(最好使用tarfile)到一个文件中。
所以我有5个名为“example1”的文件,每个文件都有不同的文件扩展名。我需要将它们拼接在一起并输出为“example1.tar”或类似的东西。
使用简单的for循环就足够了,例如:
tar = tarfile.open('example1.tar',“w”)
表示glob('example1 *')中的输出:
tar.add(输出)
tar.close()
但是,有300个“示例”文件,我需要遍历每个文件及其相关的5个文件才能使其工作。这是我的头脑。任何建议都非常感谢。
答案 0 :(得分:2)
你可以这样做:
这样的事情:
import os
import tarfile
from collections import defaultdict
myfiles = os.listdir(".") # List of all files
totar = defaultdict(list)
# now fill the defaultdict with entries; basename as keys, extensions as values
for name in myfiles:
base, ext = os.path.splitext(name)
totar[base].append(ext)
# iterate through all the basenames
for base in totar:
files = [base+ext for ext in totar[base]]
# now tar all the files in the list "files"
tar = tarfile.open(base+".tar", "w")
for item in files:
tar.add(item)
tar.close()
答案 1 :(得分:2)
您所描述的模式概括为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)
答案 2 :(得分:1)
你必须遇到问题。单独解决。
查找匹配的名称。使用collections.defaultict
找到匹配的名称后创建tar文件。你已经很好地覆盖了它。
因此。首先解决问题1。
使用glob
获取所有名称。使用os.path.basename
拆分路径和基本名称。使用os.path.splitext
拆分名称和扩展名。
列表字典可用于保存所有具有相同名称的文件。
这就是你在第1部分中所做的事情吗?
第2部分将文件放入tar档案中。为此,您已经拥有了所需的大部分代码。
答案 3 :(得分:0)
尝试使用glob模块:http://docs.python.org/library/glob.html
答案 4 :(得分:0)
#! /usr/bin/env python
import os
import tarfile
tarfiles = {}
for f in os.listdir ('files'):
prefix = f [:f.rfind ('.') ]
if prefix in tarfiles: tarfiles [prefix] += [f]
else: tarfiles [prefix] = [f]
for k, v in tarfiles.items ():
tf = tarfile.open ('%s.tar.gz' % k, 'w:gz')
for f in v: tf.addfile (tarfile.TarInfo (f), file ('files/%s' % f) )
tf.close ()
答案 5 :(得分:-1)
import os
import tarfile
allfiles = {}
for filename in os.listdir("."):
basename = '.'.join (filename.split(".")[:-1] )
if not basename in all_files:
allfiles[basename] = [filename]
else:
allfiles[basename].append(filename)
for basename, filenames in allfiles.items():
if len(filenames) < 2:
continue
tardata = tarfile.open(basename+".tar", "w")
for filename in filenames:
tardata.add(filename)
tardata.close()