python中文件的条件复制

python中文件的条件复制,python,shutil,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/a

因此,如果文件名以与列表中的值相同的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")
我试图复制的文件示例,即源文件

目标目录为空

一些重要的事情:ok_ID不包含不同的值,但我希望程序将列表视为包含不同的值。例如,8397在ok_ID列表中出现两次,在ok_ID循环中不需要重复两次,它是一个非常长的列表,我不喜欢编辑。源通常也可以包含重复的id,使用上面的示例,这些id是0000、8652,但文件名的其余部分不同

总之。。。如果0000在我的ok_ID列表中,并且在我的源目录中有以0000开头的文件名,那么我想将它们复制到我的目标文件夹中

我已经研究过使用.startswith,但使用列表作为参数并不愉快,即使我将其转换为一个元组,然后再转换为一个str。任何帮助都将是惊人的

更新

这不起作用的原因可能是某些ID包含连字符吗?还有一些是以char x而不是int值开始的

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

309-_060202_112353.txt
x104_051203_064013.txt
这应该起作用:

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:
你在比较一个str和一个int,直觉上,这总是错误的

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

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

您的代码对我有效,只需稍微修改strx而不是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_ID中的所有项转换为字符串,然后查看这会产生什么:

ok_ids = [str(id) for id in ok_ids]
files_matched = [file for file in source if file[:4] in ok_ids]
files[:4]==x永远不能为真,因为x是整数,files[:4]是字符串。x的字符串表示形式是否匹配并不重要:

我已经研究过使用.startswith,但使用列表作为参数并不愉快,即使我将其转换为一个元组,然后再转换为一个str。任何帮助都将是惊人的

这可以说是解决这个问题的最佳方法,但您不仅需要一个元组,还需要将各个ID值设置为字符串。没有可能的强制转换,它们不是您可以在影响元素的ok_ID上执行的真正强制转换

最简单的方法是首先创建一个元组,然后让元组的元素首先是字符串:

ok_ids = (
    '5252',
    '8396',
    # ...
    '1368'
)
如果不控制此数据,则可以使用传递给tuple的生成器表达式来创建tuple:

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

嗯,它仍然在复制错误的数据。它将复制整个目录,而不仅仅是以ID开头的文件list@Abbie那没有道理。你检查过列表是否包含所有内容吗?是的,只是双重检查:/n刚刚做了一次布尔检查,它总是返回True,这是我以前遇到的情况,这就是为什么我认为startswith不适用于此情况。我还得到了ValueError:对于以10为基数的int,文本无效:使用edit if intfile.split\u0在ok_id中:并不是所有id都以int开头,我本应该提到的。我认为ok_id不起作用的原因是ok_id是一个整数列表,而不是字符串。谢谢@Bill,经过3个小时的尴尬思考,我终于把它修好了!我只能假设连字符和字符有时是ID的一部分,无论如何我都无法理解。谢谢你的来信
ok_ids = (
    '5252',
    '8396',
    # ...
    '1368'
)
ok_ids = tuple(str(x) for x in ok_ids)