使用python将文件复制到文件列表中指定的目录

时间:2009-08-15 13:50:33

标签: python file copy directory

我在一个目录中有一堆文件,我想在子目录中组织。

此目录结构(哪个文件将放在哪个目录中)在文件列表中指定,如下所示:

Directory: Music\

-> 01-some_song1.mp3

-> 02-some_song2.mp3

-> 03-some_song3.mp3

Directory: Images\

-> 01-some_image1.jpg

-> 02-some_image2.jpg

......................

我正在考虑提取数据(目录名和文件名)并将其存储在如下字典中:

dictionary = {'Music': (01-some_song1.mp3, 02-some_song2.mp3,
                         03-some_song3.mp3),
              'Images': (01-some_image1.jpg, 02-some_image2.jpg),
          ......................................................
}

之后我会在各自的目录中复制/移动文件。

我已经提取了目录名称并创建了空目录。

对于字典值,我尝试通过执行以下操作获取列表列表:

def get_values(file):
    values = []
    tmp = []
    pattern = re.compile(r'^-> (.+?)$')
    for line in file:
        if line.strip().startswith('->'):
            match = re.search(pattern, line.strip())
            if match:
                tmp.append(match.group(1))
        elif line.strip().startswith('Directory'):
            values.append(tmp)
            del tmp[:]
    return values

这似乎不起作用。 values列表中的每个列表一遍又一遍地包含相同的4个文件名。

我做错了什么?

我还想知道做这件事的其他方法是什么?我确信有更好/更简单/更清洁的方式。

3 个答案:

答案 0 :(得分:1)

我认为原因是你总是重复使用相同的列表。

del tmp[:]清除列表,但不创建新实例。在您的情况下,您需要通过调用tmp = []

来创建新列表

以下修复应该有效(我没有测试)

def get_values(file):
    values = []
    tmp = []
    pattern = re.compile(r'^-> (.+?)$')
    for line in file:
        if line.strip().startswith('->'):
            match = re.search(pattern, line.strip())
            if match:
                tmp.append(match.group(1))
        elif line.strip().startswith('Directory'):
            values.append(tmp)
            tmp = []
    return values

答案 1 :(得分:1)

无需使用正则表达式

d = {}
for line in open("file"):
    line=line.strip()
    if line.endswith("\\"):
        directory = line.split(":")[-1].strip().replace("\\","")
        d.setdefault(directory,[])
    if line.startswith("->"):
        song=line.split(" ")[-1]
        d[directory].append(song)
print d

输出

# python python.py
{'Images': ['01-some_image1.jpg', '02-some_image2.jpg'], 'Music': ['01-some_song1.mp3', '02-some_song2.mp3', '03-some_song3.mp3']}

答案 2 :(得分:0)

如果使用collections.defaultdict(list),则会得到一个列表,其中的元素是列表。如果未找到该键,则会为其添加一个空列表值,以便您可以立即开始追加该列表。这就是这条线的作用:

d[dir].append(match.group(1))

如果目录名不存在,则将其创建为密钥,并将找到的文件名附加到列表中。

顺便说一句,如果你在使用正则表达式时遇到问题,请尝试使用debug标志创建它们。我不记得符号名称,但数字是128.所以如果你这样做:

file_regex = re.compile(r'^-> (.+?)$', 128)

你得到这个额外的输出:

at at_beginning
literal 45
literal 62
literal 32
subpattern 1
  min_repeat 1 65535
    any None
at at_end

你可以看到有一个起始线匹配' - > '(对于45 62 32)然后重复任何模式和行尾匹配。对调试非常有用。

代码:

from __future__ import with_statement

import re
import collections

def get_values(file):
    d = collections.defaultdict(list)
    dir = ""
    dir_regex = re.compile(r'^Directory: (.+?)\\$')
    file_regex = re.compile(r'\-\> (.+?)$')
    with open(file) as f:
        for line in f:
            line = line.strip()
            match = dir_regex.search(line)
            if match:
                dir = match.group(1)
            else:
                match = file_regex.search(line)
                if match:
                    d[dir].append(match.group(1))
    return d

if __name__ == '__main__':
    d = get_values('test_file')
    for k, v in d.items():
        print k, v

结果:

Images ['01-some_image1.jpg', '02-some_image2.jpg']
Music ['01-some_song1.mp3', '02-some_song2.mp3', '03-some_song3.mp3']