2017-08-31 65 views
1

我需要获取不同文件夹中最大尺寸的文件,将它们的名称更改为它们所属的文件夹名称并保存到一个新的文件夹。我有这样的事情,我卡住了:如何获取文件夹中最大尺寸的文件,更改其名称并保存到其他文件夹

import os 

# Core settings 
rootdir = 'C:\\Users\\X\\Desktop\\humps' 
to_save = 'C:\\Users\\X\\Desktop\\new' 

for root, dirs, files in os.walk(rootdir): 
     new_list = [] 
     for file in files: 
      if file.endswith(".jpg"): 
       try: 
        print(file) 
        os.chdir(to_save) 
        add_id = root.split("humps\\")[1] 
        add_id = add_id.split("\\")[0] 
        file_name = os.path.join(root,file) 
        new_list.append(file_name) 
        bigfile = max(new_list, key=lambda x: x.stat().st_size) 


       except: 
        pass 

为了更清楚:比方说,子文件夹的名称是“大象”,并有不同的大象照片和子文件夹在这头大象的文件夹。我想通过这些照片和子文件夹,找到最大尺寸的大象照片,将其命名为大象并将其保存到我的目标文件夹中。还为其他子文件夹,如狮子,美洲狮等重新调整它。 我怎么能达到我想要的?

+0

因此,让我们假设有不同的文件夹,每个文件夹都有很多文件。对于那些文件夹,我想以kbs的方式获得最大尺寸的文件 – edyvedy13

+0

如果文件夹中有多个文件的最大尺寸,您想要做什么?您是否需要扫描rootdir文件夹中的JPEG文件,或者是否需要在这些文件夹内还需要搜索JPEG文件夹? –

+0

的确,可能有一些子文件夹。为了更清楚:假设文件夹的名称是“大象”,在这个大象文件夹中有不同的大象照片和子文件夹。我想通过这些照片和子文件夹,并找到大象最大的照片,将其命名为大象并将其保存到我的目标文件夹 – edyvedy13

回答

1

How to get the files with the biggest size in the folders, change their name and save to a different folder

基本上你已经拥有的,你需要做的一个很好的说明。你只需要按照它一步一步:

  1. 得到的所有文件在一些搜索目录
  2. 对相关的文件过滤器(“* .JPG”)
  3. 得到它们的大小
  4. 找到最大
  5. 复制到新目录与搜索目录

的名称国际海事组织这是一个重要的技能,能够将任务分解成更小的任务。然后,你只需要实现更小的任务,并结合:


def iterate_files_recursively(directory="."): 
    for entry in os.scandir(directory): 
    if entry.is_dir(): 
     for file in iterate_files_recursively(entry.path): 
     yield file 
    else: 
     yield entry 

files = iterate_files_recursively(subfolder_name) 

我会使用os.scandir,因为它避免了建立在内存中的文件(潜在的)巨大的名单,而是让我(通过发生器)一次处理一个文件。请注意,从3.6开始,可以使用os.scandir的结果作为上下文管理器(with语法)。

images = itertools.filterfalse(lambda f: not f.path.endswith('.jpg'), files) 

过滤是除的ìtertools.filterfalse国际海事组织奇怪的选择,只保留针对其谓语返回False元素相对简单。

biggest = max(images, key=(lambda img: img.stat().st_size)) 

这是一个两个步骤:获取与内置max函数的最大值,并使用该文件大小的“钥匙”,以建立一个订单。请注意,如果您没有任何图像,则会产生ValueError ...所以您可能需要提供default=None或处理该异常。

shutil.copy(biggest.path, os.path.join(target_directory, subfolder_name + '.jpg') 

shutil.copy复制文件和一些元数据。而不是硬编码路径分隔符,请使用os.path.join

现在所有这些都假设您知道subfolder_name。您也可以轻松地扫描那些:

def iterate_directories(directory='.'): 
    for entry in os.scandir(directory): 
    if entry.is_dir(): 
     yield entry 
+0

非常感谢你真棒的答案 – edyvedy13

1

这里有一些代码可以做你想做的。它不使用旧的os.walk函数,而是使用现代的pathlib函数。

此代码的核心是递归biggest函数。它会扫描folder中的所有文件和目录,将匹配的文件名保存到files列表中,并递归搜索它找到的任何目录。然后它返回找到的最大文件的路径,如果找不到匹配的文件,则返回None

from pathlib import Path 
import shutil 

def filesize(path): 
    return path.stat().st_size 

def biggest(folder, pattern): 
    ''' Find the biggest file in folder that matches pattern 
     Search recursively in all subdirectories 
    ''' 
    files = [] 
    for f in folder.iterdir(): 
     if f.is_file(): 
      if f.match(pattern): 
       files.append(f) 
     elif f.is_dir(): 
      found = biggest(f, pattern) 
      if found: 
       files.append(found) 
    if files: 
     return max(files, key=filesize) 

def copy_biggest(src, dest, pattern): 
    ''' Find the biggest file in each folder in src that matches pattern 
     and copy it to dest, using the folder's name as the new file name 
    ''' 
    for path in src.iterdir(): 
     if path.is_dir(): 
      found = biggest(path, pattern) 
      if found: 
       newname = dest/path 
       print(path, ':', found, '->', newname) 
       shutil.copyfile(found, newname) 

你可以这样调用:

rootdir = r'C:\Users\X\Desktop\humps' 
to_save = r'C:\Users\X\Desktop\new' 
copy_biggest(Path(rootdir), Path(to_save), '*.jpg') 

注意,复制的文件将具有相同的名称,他们发现在rootdir顶层文件夹,没有文件扩展名。如果你想给他们一个.jpg扩展,你可以改变

newname = dest/path 

newname = (dest/path).with_suffix('.jpg') 

shutil模块上的旧版本的Python 3的不理解pathlib路径。但这很容易解决。在copy_biggest功能,更换

shutil.copyfile(found, newname) 

shutil.copyfile(str(found), str(newname)) 
+0

它引发:TypeError:参数应该是字符串,字节或整数,而不是WindowsPath – edyvedy13

+0

@ edyvedy13对不起。它在Python 3.6上运行良好。但修复起来很容易,因此它可以在Python 3.4或3.5上运行。我会编辑我的答案。 –

2

要找到最大的文件并保存到另一个位置

import os 
import shutil 

f_list = [] 

root = "path/to/directory" 
root = os.path.abspath(root) 

for folder, subfolders, files in os.walk(root): 
    for file in files: 

     filePath = os.path.join(folder, file) 
     f_list.append(filePath) 


bigest_file = max(f_list,key=os.path.getsize) 
new_path = "path/where/you/want/to/save" 
shutil.copy(biggest_file,new_path) 

,如果你只想要的图像,然后在循环

增加一个条件
for folder, subfolders, files in os.walk(root): 
    for file in files: 
     if file.endswith(".jpg"): 
      filePath = os.path.join(folder, file) 
      f_list.append(filePath) 

要获得所有文件夹的最大文件

root = "demo" 
root = os.path.abspath(root) 

def test(path): 
    big_files = [] 
    all_paths = [x[0] for x in os.walk(path)] 

    for paths in all_paths: 

     f_list = filter(os.path.isfile, os.listdir(paths)) 
     if len(f_list) > 0: 
      big_files.append((paths,max(f_list,key=os.path.getsize))) 
    return big_files 


print test(root) 
+0

它引发此错误:NameError:名称'img'未定义 – edyvedy13

+0

@ edyvedy13我更新我的答案,请检查它 – Kallz

+0

我应该将bigest_file放入循环中? ValueError:max()arg是一个空序列 – edyvedy13

相关问题