【问题标题】:Making multiple copies of a single file in the same directory在同一目录中制作单个文件的多个副本
【发布时间】:2021-08-10 02:43:30
【问题描述】:

给你一个格式如下的数组:

file_name_and_desti_subdir
    = [['1020','A']
       ['1020','A']
       ['1106','A']
       ['1003','B']
       ['1003','B']
       ['1004','C']
       ['1005','C']]

使用此数组,您应该从给定目录复制到给定目标目录。 “1013”指定一个不带扩展名的文件名,“A”指定目标的子目录。

所以代码运行完成后,文件结构应该是这样的:

Destination 
  A
     1020.jpg
     1020(1).jpg
     1106.jpg
  B
     1003.jpg
     1003(1).jpg
  C
     1004.jpg
     1005.jpg

为此,您需要从源文件中选择正确的项目并将其复制到目标文件中的所需位置。

这就是我厌倦的地方。 (或者至少是它的简化版本)

from shutil import copy
from os import wlak, path

def copyFile(source, desti, file_name_and_desti_subdir)

    for item in file_name_and_desti_subdir:
        for root, subdir, files in walk(source): #using os.walk to find correct item in source
            for file in files:

                item_source_path = path.join(root, file) #constructing source path of item

                if file.split('.')[0] == item[0]: #choice structure
                    if item[1] == 'A':
                        copy(item_source_path, desti + "\\A")
                    elif item[1] == 'B':
                        copy(item_source_path, desti + "\\B")
                    elif item[1] == 'C':
                        copy(item_source_path, desti + "\\C")

然而,此代码将产生以下文件结构:

Destination 
  A
     1020.jpg
     1106.jpg
  B
     1003.jpg
  C
     1004.jpg
     1005.jpg

请注意,已复制两次的项目不包括在内,因为它们已被覆盖。我的问题是如何防止这种形式发生。

附言

我有一个单独的函数来处理在目标文件夹中创建文件结构。

【问题讨论】:

  • 该功能称为“文件名版本控制”,例如:code.activestate.com/recipes/52663-versioning-file-names
  • @VPfB 您提供的示例即将解决我的问题。但是,它需要事先知道我想要制作的副本数量。我会按照建议尝试制作 MRE。
  • @pippo1980 我重组了我的问题。我希望现在更容易理解。
  • @Christopher:根据您的示例,您知道何时会发生冲突,因为您的代码已经使用了(未修饰的)名称。

标签: python filesystems


【解决方案1】:

我的尝试:


import numpy as np

file_name_and_desti_subdir = np.array([['1020','A'],
       ['1020','A'],
       ['1106','A'],
       ['1003','B'],
       ['1003','B'],
       ['1004','C'],
       ['1005','C']]) #.astype('object')
    
    
print(file_name_and_desti_subdir, file_name_and_desti_subdir.size, file_name_and_desti_subdir.shape, 
      file_name_and_desti_subdir.ndim, file_name_and_desti_subdir.dtype)

from shutil import copy,copyfile
from os import walk, path, makedirs

def copyFilez(source, desti, file_name_and_desti_subdir):
    nA = 1
    nB = 1
    nC = 1
    for item in file_name_and_desti_subdir:
        print('ITEM :', item)
        for root, subdir, files in walk(source): #using os.walk to find correct item in source
            print('root : ',root)
            print('subdir :',subdir)
            for file in files:
                print(file, item[1])
                item_source_path = path.join(root, file) #constructing source path of item
                print('item_source_path : ', item_source_path)
                if file.split('.')[0] == item[0]: #choice structure
                    if item[1] == 'A':
                        print(desti + "/A/"+file)
                        if not path.exists(desti + "/A"):
                            makedirs(desti + "/A", exist_ok=True)
                        if path.isfile('/'+desti + r"/A/"+file) == True:
                            copy(item_source_path, '/'+desti + "/A/"+file.split('.')[0]+'_'+str(nA)+'.'+file.split('.')[1]) 
                            nA += 1 
                        else:
                            copyfile(item_source_path, desti + "/A/"+file )
                    elif item[1] == 'B':
                        if not path.exists(desti + "/B/"):
                            makedirs(desti + "/B", exist_ok=True)
                        if not path.isfile(desti + "/B/"+file):
                            copy(item_source_path, desti + "/B/"+file)
                        else:
                            copy(item_source_path, desti + "/B/"+file.split('.')[0]+'_'+str(nB)+'.'+file.split('.')[1])
                            nB += 1 
                    elif item[1] == 'C':
                        if not path.exists(desti + "/C"):
                            makedirs(desti + "/C", exist_ok=True)
                        if not path.isfile(desti + "/C/"+file):
                            copy(item_source_path, desti + "/C/"+file)
                        else:
                            copy(item_source_path, desti + "/C/"+file.split('.')[0]+'_'+str(nC)+'.'+file.split('.')[1])
                            nC += 1 

        
copyFilez('SOURCE', 'DEST', file_name_and_desti_subdir)

按照 Cristophher 的建议,我重新编写了脚本,为每个文件编号并使用数组来计算每个文件出现在不同部分的时间:

from shutil import copy
from os import walk, path, makedirs
import numpy as np

file_name_and_desti_subdir = np.array([['1020', 'A'],
                                       ['1020', 'A'],
                                       ['1106', 'A'],
                                       ['1003', 'B'],
                                       ['1003', 'B'],
                                       ['1004', 'C'],
                                       ['1005', 'C'],
                                       ['1205', 'A'],
                                       ['1205', 'A'],
                                       ['1205', 'A'],
                                       ['1205', 'A'],
                                       ['1205', 'B'],
                                       ['1205', 'C']])  # .astype('object')



def copyFilez(source, desti, file_name_and_desti_subdir_copy):
    file_name_and_desti_subdir_copy = np.zeros((file_name_and_desti_subdir.shape[0]) ,dtype = "object")

    for i in range(file_name_and_desti_subdir.shape[0]):
        file_name_and_desti_subdir_copy[i] = file_name_and_desti_subdir[i,0]+file_name_and_desti_subdir[i,1]
        
    file_name_and_desti_subdir_copy2 = np.zeros((file_name_and_desti_subdir.shape[0],4) ,dtype = "object")
    
    for i in range(file_name_and_desti_subdir_copy.shape[0]):
        file_name_and_desti_subdir_copy2[i,0] = file_name_and_desti_subdir[i,0]
        file_name_and_desti_subdir_copy2[i,1] = file_name_and_desti_subdir[i,1]
        file_name_and_desti_subdir_copy2[i,2] = file_name_and_desti_subdir_copy[i]
        file_name_and_desti_subdir_copy2[i,3] = str(np.count_nonzero(file_name_and_desti_subdir_copy[:i+1] == file_name_and_desti_subdir_copy[i])).zfill(6)
        
    print(file_name_and_desti_subdir_copy2, file_name_and_desti_subdir_copy2.size, file_name_and_desti_subdir_copy2.shape)
    
    
    
    for item in file_name_and_desti_subdir_copy2:
        print('ITEM :', item)
        # using os.walk to find correct item in source
        for root, subdir, files in walk(source):
            print('root : ', root)
            print('subdir :', subdir)
            for file in files:
                print(file, item[1])
                # constructing source path of item
                item_source_path = path.join(root, file)
                print('item_source_path : ', item_source_path)
                if file.split('.')[0] == item[0]:  # choice structure
                    if item[1] == 'A':
                        print(desti + "/A/"+file)
                        if not path.exists(desti + "/A"):
                            makedirs(desti + "/A", exist_ok=True)
                        copy(item_source_path, desti + "/A/"+file.split('.')[0]+"_"+ item[3] + "." +file.split('.')[1])


                    elif item[1] == 'B':
                        if not path.exists(desti + "/B/"):
                            makedirs(desti + "/B", exist_ok=True)
                        copy(item_source_path, desti + "/B/"+file.split('.')[0]+"_"+ item[3] + "." +file.split('.')[1])
                    elif item[1] == 'C':
                        if not path.exists(desti + "/C"):
                            makedirs(desti + "/C", exist_ok=True)
                        copy(item_source_path, desti + "/C/"+file.split('.')[0]+"_"+ item[3] + "." +file.split('.')[1])

copyFilez('SOURCE', 'DESTinazione', file_name_and_desti_subdir)

它会创建两个新数组,最后一个是:

[['1020' 'A' '1020A' '000001']
 ['1020' 'A' '1020A' '000002']
 ['1106' 'A' '1106A' '000001']
 ['1003' 'B' '1003B' '000001']
 ['1003' 'B' '1003B' '000002']
 ['1004' 'C' '1004C' '000001']
 ['1005' 'C' '1005C' '000001']
 ['1205' 'A' '1205A' '000001']
 ['1205' 'A' '1205A' '000002']
 ['1205' 'A' '1205A' '000003']
 ['1205' 'A' '1205A' '000004']
 ['1205' 'B' '1205B' '000001']
 ['1205' 'C' '1205C' '000001']]

并以np.count_nonzero计数

编号的零由str(number)zfill()添加

【讨论】:

  • 我实际上认为这比我的解决方案更有效。因为我在数组中的每个项目上使用.count 并检查它是否大于 2,以查找所有重复项及其数量,因此可以找到哪些项目以及运行 FileVersion 的时间;这是O(n ^ 2)。这个解决方案很好而且是线性的。如果我错了,请纠正我,但如果你在数组中遇到第二个重复项,它不会继续计算最后一个重复项停止的位置。类似“1000_1.jpg, 1000_2.jpg.....then.....1055_3.jpg, 1055_4.jpg”的东西,如果他们都是 A。老实说,这并不是一个问题。仍然有效。
  • @christopher 。是的,您对编号问题是正确的。我的重点是 os.makedirs,因为将不存在的路径传递给 os.copy() 时出错
  • 如果我有时间我会按照你的建议尝试新的数组方法,
【解决方案2】:

对于任何感兴趣的人,我最终使用了 VPfB 在 cmets 中提供的示例。他提供的例子不是他自己的。它是用 python 2 编写的,因此必须进行一些更改。它还将文件的版本附加到扩展名中,这会引起一些麻烦。 (Original Example) 这是我调整后的版本。

   from os import path
   from shutil import copy

    def VersionFile(source, destination):
        if path.isfile(destination):
            name, extension = path.splitext(destination)
            for i in range(1000):
                new_file = f'{name} ({i}){extension}'
                if not path.isfile(new_file):
                    copy(source, new_file)
                    break

为此,我还需要在数组中查找任何重复项,然后计算每个重复项出现的次数。我将重复项保存在一个数组中,然后将它们出现在另一个并行数组中的次数。

然后在核心循环中,我将 ifs 和 elifs 更改如下:

if item[1] == 'A':
     copy(item_source_path, desti + "\\A")
     if item in duplicates:
         for i in range(duplicates_count[duplicates.index(item)])
              VersionFile(item_source_path,  desti + "\\A\\" + file)
     break

(添加中断以减少运行时间)

然后在第一个 for 循环之后,我添加了一个检查以确保忽略该项目的所有后续出现。从现在开始,我还需要逐项引用。 (重复项将始终紧挨着显示。)。

   for i in range(len(file_name_and_desti_subdir):
       item = file_name_and_desti_subdir[i]
          if package == file_name_and_desti_subdir[i - 1]:
             pass
          else:
             ...(main loop)

【讨论】:

  • 现在传递路径到 shutil.copy 有效吗?试图回答(留给周末)并得到了一些错误,我归咎于stackoverflow.com/questions/2793789/…
  • 我一直在传递诸如“C:\\foo\\bar”之类的字符串,但没有收到任何错误。
  • 好的,谢谢。我在上面的链接中使用:“如果 ./a/b/c 中不存在诸如 b/c/ 之类的路径,则 shutil.copy("./blah.txt", "./a/b /c/blah.txt") 会抱怨目的地不存在。创建目标路径并将文件复制到此路径的最佳方法是什么?”的方法。
猜你喜欢
  • 2023-04-02
  • 1970-01-01
  • 2021-07-18
  • 2017-08-14
  • 2016-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-02
相关资源
最近更新 更多