windows下文件(文件夹)的批量创建、移动、重命名

文章介绍了如何利用Windows自带的命令行工具CMD和Excel进行批量文件操作,如创建文件夹、移动文件等,尤其适合不熟悉编程但需要自动化办公任务的用户。通过在Excel中生成CMD命令,然后保存为批处理文件执行,可以实现简单的文件管理自动化,尽管效率可能低于专门的三方工具或编程解决方案。

一、前言

引子在日常办公中我们经常会遇到批量创建文件,文件夹,把对应文件放到对应的目录中去、文件名需要按统一的格式修改等等,我们只能想办法让电脑去自动化的去做,而不是手工依次创建,本文主要说的工具是windows自带的命令结合excel去实现上述功能。(本篇只针对不会自己写代码,又懒得找三方工具的朋友,高手略过)

上述方法的优缺点:

优点:不需要写代码的能力,不用下载或寻找三方工具。只要会用excel即可上手,借助excel+cmd批处理可以自由实现一些想要的操作。

缺点:它的执行速度没有一些三方工具或者自己写的代码快(尤其是万级以上文件的批量操作)

二、基本步骤:

  1. 明确需求,准备数据到excel中
  2. 根据需求,运用excel公式生成相应的cmd命令
  3. 复制命令到文本文件,保存成 ".bat"文件(编码格式ANSI),双击运行

注:.bat文件就是批处理文件,它可以在windows上双击直接运行,本质就是一条条cmd命令的文本文件

三、实操

a. 问题引入

案例:假设现在有很多图片,他们在同一目录下,想要根据他们的文件名复制到不同的文件夹下面去,如何操作?文件如下图所示(需要把a1_*.jpg放到a1文件夹,a2_*.jpg放到a2文件夹,a10_*.jpg放到a10文件夹,b3_*.jpg放到b3文件夹等等)

 b. 问题分析

  • 我们先要得到最终文件和文件夹的一个所属关系,知道哪个文件应该放到哪个文件夹中
  • 然后我们要提前创建好目标文件夹,为后面拷贝文件做准备
  • 生成命令语句,批量执行

 c. 实战

基于上面的分析,我们依次来操作:

1. 准备基础数据到excel

      由于我们的的文件存在一个文件夹下,要想全部一次性拿出来,就得用到dir这个命令,可以列出文件夹下文件名,然后输出到txt中,复制到excel中即可

 

 win+R输入“cmd”,打开命令符窗口,进入目标文件夹的同级目录,执行命令:

得到txt内容如下 

复制到excel直接用数据分列,得到文件名 ,删除没用的列如图所示:

接着根据文件名,拿到要放入的目标文件夹,这里同样可以用数据分列得到,也可以用excel公式拿到,总之无论什么方法,拿到第一个下划线前面的内容即可。

这里用公式展示:

在B1单元格输入:=LEFT(A1,FIND("_",A1)-1), 双击填充公式,得到目标文件夹的名字,如下图:

2. 准备目标文件夹

在C1单元格输入公式:="mkdir "&b1,双击填充公式,如图所示:

将C列复制到另一个sheet,然后删除重复值,之后复制到新建的txt中(注意要在目标位置创建),另存为a.bat,双击运行 ,结果如下:

 

3. 准备复制文件命令,批量执行

在D1单元格输入公式 ="COPY test111\"&A1&" "&B1

把D列复制到文本文件中,另存为a.bat,双击运行,大功告成!

 

 

 

四、总结

运行该模式,借助excel可以完成诸多个性计的操作,只需要相应的改一下,组合命令时的公式,此篇只作为抛砖引玉的记录,大家可以自由发挥!

 

<think>我们参考上述引用内容,特别是引用[2]和引用[4]中的代码示例,来编写一个批量重命名文件的Python脚本。 用户需求:使用Python对指定文件夹内的文件进行批量重命名。 我们将设计一个函数,它接受一个文件夹路径,然后按照用户指定的规则重命名文件。 由于用户没有指定具体的重命名规则,我们可以提供几种常见的重命名方式: 1. 按顺序编号:例如将文件重命名为1.jpg, 2.jpg, ... 2. 删除文件名中的特定子字符串。 3. 替换文件名中的部分字符串。 4. 在文件名中添加前缀或后缀。 但是,用户没有给出具体规则,因此我们可以先实现一个通用的框架,并允许用户自定义重命名规则。 考虑到用户可能需要不同的规则,我们可以设计一个回调函数(或使用lambda表达式)来让用户指定如何生成新文件名。 然而,为了简单起见,我们先实现一个按顺序编号的重命名,并允许用户通过修改代码来定制规则。 参考引用[4]中的代码,它按顺序将所有的.jpg文件重命名为0.jpg, 1.jpg, ... 但是,用户可能想要重命名所有文件,而不仅仅是图片,并且可能想要保留原扩展名。 因此,我们可以设计如下: 函数:batch_rename(folder_path, rule_function) - folder_path: 文件夹路径 - rule_function: 一个函数,它接受原文件名和当前索引(可选),返回新文件名(不带路径) 但是,为了更灵活,我们也可以让用户选择是否使用索引。 然而,用户可能不需要编程接口,而是直接修改脚本。因此,我们可以先写一个简单的版本,然后让用户根据需要修改。 下面是一个基础版本,它按顺序编号,并保留原扩展名: 步骤: 1. 获取文件夹中所有文件的列表(不包括子文件夹)。 2. 遍历每个文件,获取文件名和扩展名。 3. 按照顺序生成新的文件名(例如:1,2,3...),并保持扩展名不变。 4. 使用os.rename进行重命名。 但是,为了避免覆盖,我们需要确保新文件名不会与已有的文件名冲突。我们可以先将要重命名文件列出来,然后按顺序重命名。 然而,按顺序重命名时,如果直接使用数字,可能会覆盖掉后面的文件。因此,我们可以先收集所有文件,然后按原文件名排序(或按修改时间等),然后再重命名。 另外,我们也可以先复制到一个临时文件夹,但这样需要额外空间。所以,我们可以先收集所有文件,然后按照一定的顺序(比如按文件名排序)进行重命名,然后从0开始编号。 但是,在重命名过程中,如果目标文件名已经存在,就会出错。为了避免这种情况,我们可以先使用临时文件名(例如在数字前加一个前缀),最后再统一去掉前缀?这样比较复杂。 一个简单的方法是:先全部重命名为临时文件名(比如在原文件名前加一个前缀),然后再重命名为目标文件名。但这样需要两次遍历。 另一种方法:我们可以先按倒序重命名(这样就不会覆盖),但这样需要知道新文件名和旧文件名的关系。 考虑到简单性,我们可以先按顺序生成新文件名,然后先重命名到中间文件名(比如在原文件名前加一个临时前缀),然后再重命名为目标文件名。但这样两次遍历。 或者,我们可以先创建一个新的临时文件夹,将文件移动过去并重命名,然后再移动回来?这样更安全,但需要额外的复制操作。 实际上,如果我们是按顺序编号,并且新文件名和旧文件名完全不同(全是数字),那么只要旧文件名不是数字,就不会冲突。但是,如果文件夹中已经存在数字命名的文件,可能会冲突。 因此,我们采用一个安全的方法:先给所有文件重命名为一个临时名称(例如:在原文件名前加一个随机字符串或固定前缀如"temp_"),然后再将这些临时名称的文件重命名为目标文件名。 但是,这样需要两次遍历,而且如果文件很多,效率会低。 考虑到用户可能只需要简单的重命名,我们可以先按原文件名的顺序进行编号,这样如果原文件名不是数字,那么就不会覆盖。但是,如果原文件名就是数字,且顺序和编号顺序不一致,就可能覆盖。 所以,我们决定:先按原文件名的排序(比如按名称升序)来生成一个列表,然后按这个顺序重命名。但是,在重命名时,我们使用一个临时文件名(例如:先重命名为"temp_原文件名"),然后再重命名为目标文件名。这样需要两次重命名。 为了效率,我们也可以只遍历一次,但使用一个不会冲突的临时文件名。我们可以这样: 第一次遍历:将每个文件重命名为一个临时文件名(例如:在文件名前加一个唯一的前缀,比如索引号加一个下划线,但这样还是可能冲突?) 实际上,我们可以使用一个临时文件夹来存放,但这样需要移动文件。 考虑到简单性,我们采用两次遍历: 第一次:将原文件重命名为一个临时文件名(例如:在文件名前加一个固定的前缀,如"temp_" + 原文件名) 第二次:将临时文件重命名为目标文件名(按顺序编号) 但是,这样如果用户只运行一次,那么会留下很多临时文件,而且如果中断,文件会处于临时状态。 因此,我们换一种思路:先收集所有文件,然后按照排序后的顺序,依次重命名为一个中间名称(比如:一个GUID或者时间戳?),但这样太复杂。 实际上,我们可以利用操作系统的重命名机制:只要目标文件不存在,就可以直接重命名。所以,我们可以先按排序后的文件列表,然后按顺序生成新文件名,然后检查新文件名是否存在。如果不存在,就直接重命名;如果存在,就先重命名为一个临时名称(比如在文件名前加一个随机字符串),然后再重命名为目标文件名。 这样逻辑复杂,代码量大。 考虑到用户可能只是少量文件,而且文件名原本没有规律,我们可以采用一个简单的方法:按原文件名的某种排序(比如按名称升序)后,从0开始编号,然后按顺序重命名。这样,如果新文件名和旧文件名不同,且新文件名之前不存在,那么就不会覆盖。但是,如果新文件名已经存在(比如文件夹中已经有一个0.jpg),那么就会覆盖。 因此,我们要求用户确保目标文件名不会与已有文件冲突。或者,我们可以先检查目标文件名是否存在,如果存在就跳过或报错。 但是,批量重命名通常是为了统一格式,所以目标文件名应该是全新的,不会重复。 所以,我们这样设计: 1. 获取文件夹中所有文件的列表(不包括文件夹)。 2. 对文件列表进行排序(比如按名称、按修改时间等,这里我们按名称排序)。 3. 遍历排序后的文件列表,对每个文件: old_path = os.path.join(folder_path, old_name) 获取扩展名:ext = os.path.splitext(old_name)[1] 新文件名 = f"{index}{ext}" # 这里index从0开始,也可以从1开始,用户可以修改 new_path = os.path.join(folder_path, new_name) 如果new_path已经存在,则报错(或跳过,或自动生成一个不重复的名字,比如在后面加(1)) 否则,重命名。 但是,如果用户希望保留原文件名的部分内容,或者添加前缀后缀,那么我们需要提供更灵活的方式。 因此,我们设计一个规则函数,由用户自定义。在规则函数中,用户可以根据原文件名和索引生成新文件名。 下面我们写一个函数,它接受文件夹路径和一个规则函数。规则函数签名为:rule(old_name, index) -> new_name(不带路径) 然后我们遍历文件,应用规则函数,然后重命名。 但是,为了避免冲突,我们可以在规则函数中要求用户保证新文件名不重复?或者我们在函数内部检查新文件名是否存在,如果存在则自动在名字后面加上序号(比如如果新文件名存在,则尝试新文件名_1,再存在则新文件名_2,直到不重复)。 考虑到用户可能希望完全控制,我们也可以不处理冲突,直接报错。 我们先写一个基础版本,不处理冲突,由用户确保规则函数返回的文件名不重复。 代码结构: def batch_rename(folder_path, rule_func): files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))] # 排序,以便顺序编号 files.sort() for index, filename in enumerate(files): # 获取扩展名 base, ext = os.path.splitext(filename) new_name = rule_func(filename, index, base, ext) # 这里我们传递原文件名、索引、原基本名和扩展名 # 如果规则函数返回的新文件名没有包含扩展名,我们可以加上扩展名?或者规则函数自己处理扩展名 # 这里我们假设规则函数返回的是完整文件名(包括扩展名),这样更灵活,因为用户可能想改变扩展名。 old_file = os.path.join(folder_path, filename) new_file = os.path.join(folder_path, new_name) try: os.rename(old_file, new_file) print(f"重命名: {filename} -> {new_name}") except Exception as e: print(f"重命名 {filename} 失败: {str(e)}") 然后,用户需要自己定义规则函数。例如,按顺序编号的规则函数可以这样写: def sequential_rule(old_name, index, base, ext): return f"{index+1}{ext}" # 从1开始编号,保留原扩展名 但是,用户可能不想改变文件名的基本部分,只想添加前缀或后缀。例如: def add_prefix_rule(old_name, index, base, ext): return f"prefix_{base}{ext}" 或者删除特定字符串: def remove_substring_rule(old_name, index, base, ext): # 删除base中的特定子字符串,比如"temp_" new_base = base.replace("temp_", "") return f"{new_base}{ext}" 这样,用户就可以自定义规则。 但是,用户可能希望不修改代码就能使用,所以我们可以提供几个预设的规则,通过参数选择。 不过,由于用户问题中没有指定具体规则,我们先提供一个按顺序编号的示例,并允许用户修改规则函数。 下面我们写一个完整的示例,并包含一个按顺序编号的规则。 注意:为了避免重名冲突,我们在重命名之前检查新文件是否存在,如果存在则报错并跳过。 改进代码: def batch_rename(folder_path, rule_func): files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))] files.sort() # 按文件名排序 for index, filename in enumerate(files): old_path = os.path.join(folder_path, filename) # 如果old_path不是文件,跳过(但我们已经过滤了) base, ext = os.path.splitext(filename) new_name = rule_func(filename, index, base, ext) new_path = os.path.join(folder_path, new_name) if os.path.exists(new_path): print(f"警告:目标文件 {new_name} 已存在,跳过重命名 {filename}") continue try: os.rename(old_path, new_path) print(f"重命名: {filename} -> {new_name}") except Exception as e: print(f"重命名 {filename} 失败: {str(e)}") 然后,我们定义规则函数,并调用。 但是,用户可能不想定义函数,所以我们也可以直接在调用时用lambda表达式。 示例:按顺序编号(从1开始,保留扩展名) rule = lambda old_name, index, base, ext: f"{index+1}{ext}" 然后调用:batch_rename(r"E:\your_folder", rule) 另外,用户可能希望保留原文件名的部分,比如引用[2]中只保留第一个下划线之前的部分。 我们可以这样定义规则: rule = lambda old_name, index, base, ext: base.split('_')[0] + ext 但是,注意:原文件名可能包含多个扩展名?所以使用os.path.splitext已经分离了最后一个扩展名。 因此,我们这样写是安全的。 下面我们给出一个完整的脚本示例,用户只需修改folder_path和rule_func即可。 注意:在重命名过程中,如果规则函数返回的新文件名重复,那么后面的文件会跳过。所以用户要确保规则函数返回的名字不重复。 另外,我们也可以提供一种更安全的模式:先将要重命名文件复制到另一个文件夹?但这样不是重命名而是备份了。所以不采用。 现在,我们写一个完整的示例代码,并加上详细的注释。 注意:由于重命名操作不可逆,建议用户先备份文件。 代码示例:</think>以下是一个使用 Python 批量重命名文件夹文件的完整解决方案,结合了多种常见需求场景的实现方法: ### 基础批量重命名脚本 ```python import os def batch_rename(folder_path, prefix="", suffix="", start_num=1): """ 批量重命名文件夹内的所有文件(保留原扩展名) 参数: folder_path: 文件夹路径(建议使用原始字符串 r"E:\your\folder") prefix: 文件名前缀(可选) suffix: 文件名后缀(可选) start_num: 起始编号(默认为1) """ # 获取文件列表(排除子文件夹) files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))] # 按文件名排序 files.sort() for i, filename in enumerate(files, start=start_num): # 分离文件名和扩展名 name, ext = os.path.splitext(filename) # 构建新文件名(格式:前缀+编号+后缀+扩展名) new_name = f"{prefix}{i}{suffix}{ext}" # 构建完整路径 old_path = os.path.join(folder_path, filename) new_path = os.path.join(folder_path, new_name) # 执行重命名 os.rename(old_path, new_path) print(f"重命名: {filename} -> {new_name}") # 使用示例 if __name__ == "__main__": folder = r"E:\your\folder\path" # 替换为你的文件夹路径 batch_rename(folder, prefix="IMG_", suffix="_backup", start_num=1) ``` ### 常见场景扩展功能 #### 1. 按特定规则重命名(保留部分字符) ```python def rename_with_rule(folder_path, separator="_", keep_segments=1): """ 按分隔符规则重命名(如保留文件名中第一个下划线前的部分) 参数: separator: 分隔符(默认下划线) keep_segments: 保留的分段数量 """ for filename in os.listdir(folder_path): if os.path.isfile(os.path.join(folder_path, filename)): # 分离文件名和扩展名 name, ext = os.path.splitext(filename) # 按规则处理文件名 parts = name.split(separator) new_name = separator.join(parts[:keep_segments]) + ext # 执行重命名 old_path = os.path.join(folder_path, filename) new_path = os.path.join(folder_path, new_name) os.rename(old_path, new_path) ``` #### 2. 添加序号补零(001, 002...) ```python def rename_with_zeropad(folder_path, prefix="", digits=3): """ 添加补零序号(如 001.jpg, 002.jpg) 参数: digits: 序号位数(默认3位) """ files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))] files.sort() for i, filename in enumerate(files, 1): _, ext = os.path.splitext(filename) new_name = f"{prefix}{i:0{digits}d}{ext}" old_path = os.path.join(folder_path, filename) new_path = os.path.join(folder_path, new_name) os.rename(old_path, new_path) ``` #### 3. 替换/删除特定字符串 ```python def replace_in_filename(folder_path, old_str, new_str=""): """ 替换或删除文件名中的特定字符串 参数: old_str: 需要替换的字符串 new_str: 替换后的字符串(留空则删除) """ for filename in os.listdir(folder_path): if os.path.isfile(os.path.join(folder_path, filename)): new_name = filename.replace(old_str, new_str) if new_name != filename: # 避免无意义重命名 old_path = os.path.join(folder_path, filename) new_path = os.path.join(folder_path, new_name) os.rename(old_path, new_path) ``` ### 使用注意事项 1. **路径格式**:建议使用原始字符串(如 `r"E:\photos"`)避免转义问题 2. **文件备份**:操作前建议复制文件夹进行测试 3. **排序控制**: - 添加 `files.sort(key=os.path.getmtime)` 可按修改时间排序 - 添加 `files.sort(key=os.path.getsize)` 可按文件大小排序 4. **过滤文件类型**: ```python # 只处理图片文件 files = [f for f in os.listdir(folder_path) if f.lower().endswith(('.png', '.jpg', '.jpeg'))] ``` ### 完整应用示例 ```python import os from datetime import datetime def smart_rename(folder_path): """智能重命名:日期前缀+序号+原文件名关键词""" today = datetime.now().strftime("%Y%m%d") files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))] for i, filename in enumerate(files, 1): # 获取文件名关键词(第一个下划线前的部分) name_key = filename.split('_')[0] if '_' in filename else os.path.splitext(filename)[0] # 保留原扩展名 _, ext = os.path.splitext(filename) # 构建新文件名 new_name = f"{today}_{i:03d}_{name_key}{ext}" # 执行重命名 os.rename( os.path.join(folder_path, filename), os.path.join(folder_path, new_name) ) print(f"Renamed: {filename} → {new_name}") # 使用示例 if __name__ == "__main__": smart_rename(r"E:\photo_archive") ``` ### 常见问题解决 1. **权限错误**:确保文件未被其他程序占用 2. **文件名冲突**:脚本会自动跳过已存在的目标文件名 3. **特殊字符处理**:添加异常处理 ```python try: os.rename(old_path, new_path) except OSError as e: print(f"Error renaming {filename}: {str(e)}") ``` ### 安全建议 1. 首次使用前在测试文件夹中验证 2. 添加干运行模式(只显示不执行): ```python def dry_run(folder_path): for filename in os.listdir(folder_path): # ...计算新文件名... print(f"[Dry Run] {filename} → {new_name}") # 不执行实际重命名 ```
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值