更有效地将文件移动到新创建的文件夹

时间:2017-04-17 18:27:22

标签: python

我想根据名称中的某个子字符串将文件列表分组到子文件夹中

文件的格式为

  • pie_riverside_10.png
  • stack_oak_20.png
  • scatter_mountain_10.png

我希望使用起始子字符串(例如饼图,堆栈,散点图)和整数子字符串(例如10,20)作为分组文件的子目录名称。

下面的代码只是示例 - 如果我实际采用这种方法,我必须使用elif语句手动创建至少75-80个文件夹,效率很低。

我很好奇是否有更好的方法可以做到这一点?

编辑:当前代码假设已经创建了一个文件夹,但在实际场景中我没有创建文件夹,我不想创建70-80子文件夹 - 我试图创建脚本来创建那些文件夹给我。

import shutil
import os

source = 'C:/Users/Xx/Documents/plots/'

pie_charts_10= 'C:/Users/Xx/Documents/pie_charts_10/'
pie_charts_20= 'C:/Users/Xx/Documents/pie_charts_20/'
stack_charts_10 = 'C:/Users/Xx/Documents/stack_charts_10 /'
scatter_charts_10 = 'C:/Users/Xx/Documents/scatter_charts_10 /'

files = os.listdir(source)

for f in files:
    if (f.startswith("pie") and f.endswith("10.png")):
        shutil.move(os.path.join(source, f), pie_charts_10)
    elif (f.startswith("pie") and f.endswith("20.png")):
        shutil.move(os.path.join(source, f), pie_charts_20 )
    elif (f.startswith("stack") and f.endswith("10.png")):
        shutil.move(os.path.join(source, f), stack_charts_10 )
    elif (f.startswith("scatter ") and f.endswith("10.png")):
        shutil.move(os.path.join(source, f), scatter_charts_10 )
    else:
        print("No file")

2 个答案:

答案 0 :(得分:3)

当您要将格式为prefix_suffix.png的文件移至文件夹prefix_charts_suffix/时:

base = "C:/Users/Xx/Documents"
moved_types = ['png']

for f in files:
    pf = f.rsplit('.', 1)  # filename, prefix
    sf = pf[0].split("_")  # prefix, whatever, suffix
    if len(sf) >= len(pf) > 1 and pf[1] in moved_types:
        new_dir = "%s_charts_%s" % (sf[0], sf[-1])
        if not os.path.exists(os.path.join(base, new_dir):
            os.mkdirs(os.path.join(base, new_dir)
        shutil.move(os.path.join(source, f), os.path.join(base, new_dir, f)

这适用于一般情况,仅抓取并移动以moved_types结尾并包含_的文件(允许分割prefixsuffix )。

请参阅repl.it上的相关逻辑:

>>>['prefix_garbage_suffix.png', 'bob.sh', 'bob.bill.png', "pie_23.png", "scatter_big_1.png"]
Move prefix_garbage_suffix.png to prefix_charts_suffix
Move pie_23.png to pie_charts_23
Move scatter_big_1.png to scatter_charts_1

编辑:我保留了原始答案,以防其他人需要解决方案,而不是每个文件都应该被移动,或者您无法从文件名中推断文件夹名称。

如果你需要,我会做类似的事情:

identity_tuples = \
[('pie', '16.png', 'C:/Users/Xx/Documents/pie_charts/'),
 ('stack', '14.png', 'C:/Users/Xx/Documents/stack_charts/'),
 ('scatter', '12.png', 'C:/Users/Xx/Documents/scatter_charts/')]

files = os.listdir(source)

for f in files:
  for identity_tuple in identity_tuples:
    if f.startswith(identity_tuple[0]) and f.endswith(identity_tuple[1]):
      shutil.move(os.path.join(source, f), identity_tuple[2])
      break
  else:
    print("No file")

现在您只需为每种类型添加一个新的标识元组:(prefix, suffix, destination)。如果路径对于所有目的地都是通用的,则可以将其更改为:

identity_tuples = \
[('pie', '16.png', 'pie_charts/'),
 ('stack', '14.png', 'stack_charts/'),
 ('scatter', '12.png', 'scatter_charts/')]

files = os.listdir(source)

for f in files:
  for identity_tuple in identity_tuples:
    if f.startswith(identity_tuple[0]) and f.endswith(identity_tuple[1]):
      shutil.move(os.path.join(source, f), "C:/Users/Xx/Documents/" + identity_tuple[2])
      break
  else:
    print("No file")

注意:这是使用for/else循环,只有在您点击else时才会调用break

如果您需要制作目录,请在shutil.move()

之前添加
if not os.path.exists(identity_tuple[2]):
    os.mkdirs(identity_tuple[2])  # Or "C:/Users/Xx/Documents/" + ...

答案 1 :(得分:2)

这个怎么样

SELECT *
FROM (SELECT
        CASE
            WHEN sc.company_name not in ('null', 'n/a', '')
                THEN company_name
            ELSE 'Unspecified'
        END as company, count(*) as count
    from table
    group by company
    ORDER BY count DESC
    LIMIT 5) AS x
ORDER BY CASE WHEN company = 'Unspecified' THEN 1 ELSE 0 END, count DESC, company

现在你想根据他们的开头和扩展前的数字将它们分组到子文件夹

# assume you have files in a folder
source = './files' # some directory
files = os.listdir(source)
print files
#['pie_river_1.png', 'pie_mountain_11.png', 'scatter_grass_12.png', 'stack_field_30.png']

在我的compurer上

subdir_root = './subfolders'

for f in files:
    fig_type = f.split('_')[0]
    fig_num = f.split('.png')[0].split('_')[-1]
    subdir_name = '%s_charts_%s'%(fig_type, fig_num) # name of dir, e.g. pie_charts_10
    subdir = os.path.join( subdir_root, subdir_name ) # path to dir
    if not os.path.exists(subdir): # if the dir does not exist , create it
        os.makedirs(subdir)

    f_src = os.path.join( source, f) # full path to source file
    f_dest = os.path.join( subdir, f) # full path to new destination file
    shutil.copy( f_src, f_dest ) # I changed to copy so you dont screw up your original files 

显然,如果出现边缘情况,您可能需要更改代码..但这应该会给您一个良好的开端......