在python

时间:2018-04-16 03:07:37

标签: python shutil

所以我试图将文件复制到另一个目录,如果他们的文件名以与我的列表值相同的4位ID开头。 我要么将错误的数据写入文件,要么根本没有。

到目前为止我所拥有的:

import shutil
import os

ok_ids = [5252,
8396,
8397,
8397,
8556,
8004,
6545,
6541,
4392,
4392,
6548,
1363,
1363,
1363,
8489,
8652,
1368,
1368]

source = os.listdir("/Users/amm/Desktop/mypath1/")
destination = "/Users/amm/Desktop/mypath2/"

for files in source:
    for x in ok_ids:
        if files[:4] == x:
            shutil.copy(files,destination)
     else:
        print("not working")

我正在尝试复制的文件示例,即source

0000_051123_192805.txt
0000_051123_192805.txt
8642_060201_113220.txt
8652_060204_152839.txt
8652_060204_152839.txt
309-_060202_112353.txt
x104_051203_064013.txt

destination目录为空

一些重要的事情:ok_ids不包含不同的值,但我希望程序将列表视为包含不同的值。例如8397列表中出现ok_ids两次,并且它不需要在ok_ids循环中迭代两次(它是一个很长的列表而且我不喜欢编辑)。 source通常也可以包含重复的ID,使用上面的示例00008652,但文件名的其余部分不同。

总结一下......如果0000列在我的ok_ids列表中,并且0000目录中有source的文件名,那么我想将它们复制到我的destination文件夹。

我已经看过使用.startswith但是使用列表作为参数并不高兴,即使我将它转换为元组然后是str。任何帮助都会很棒。

更新

这不起作用的原因是某些ID包含连字符吗?和其他人以char x开头而不是int值?

前4个值是ID,例如它们仍然有效:

309-_060202_112353.txt
x104_051203_064013.txt

4 个答案:

答案 0 :(得分:4)

这应该有效:

for file in source:
    for x in set(ok_ids):
        if file.startswith(str(x)):
            shutil.copy(file, destination)

使用set()使数字唯一,str()转换为字符串。因此,您可以将列表预处理为一组以获得更好的性能。

或者更好的是,鉴于您的命名限制:

if int(file.split("_")[0]) in ok_ids:

为什么你的代码不起作用?

if files[:4] == x:

您将strint进行比较,直觉上,这将永远是假的。

答案 1 :(得分:1)

import os
import shutil
for root, dirs, files in os.walk("/Users/amm/Desktop/mypath1/"):
    for file in files:
        try:
            if int(file[:4]) in ok_ids:
               shutil.copy(file,destination)
        except:
            pass

这对我有用。唯一的问题是它会抓取同一目录中的所有文件夹。

答案 2 :(得分:1)

您的代码适用于我str(x)而非x的轻微修改。

尝试使用它来查看它对每个文件的作用:

for files in source:
    for x in ok_ids:
        if files[:4] == str(x):
            print("File '{}' matched".format(files))
            break
    else:
        print("File '{}' not matched".format(files))

或者,或者,将ok_ids中的所有项目转换为字符串,然后查看它产生的内容:

ok_ids = [str(id) for id in ok_ids]
files_matched = [file for file in source if file[:4] in ok_ids]

答案 3 :(得分:0)

files[:4] == x永远不会成为真,因为x是一个整数,files[:4]是一个字符串。如果 x的字符串表示匹配,无关紧要

>>> 123 == '123'
False
  

我已经看过使用.startswith但是使用列表作为参数并不高兴,即使我将它转换为元组然后是str。任何帮助都会很棒。

这可以说是解决问题的最佳方法,但您不仅需要一个元组 - 您需要将个人ID值作为字符串。您可以在ok_ids上执行影响元素的“强制转换”(它们不是真正的强制转换)。

最简单的方法是首先创建一个元组,并且首先将元组的元素作为字符串:

ok_ids = (
    '5252',
    '8396',
    # ...
    '1368'
)

如果您不控制此数据,则可以使用传递给tuple的生成器表达式来创建元组:

ok_ids = tuple(str(x) for x in ok_ids)