递归地从文件名和目录名中删除字符串的 Python 脚本
此 Python 脚本递归地重命名给定文件夹中的文件和目录,**从文件名和目录名中删除给定字符串。**它不需要安装任何库。
注意,此脚本已经过测试,但我们不能保证它在某些条件下不会破坏某些数据。备份你的数据并谨慎使用(最好先尝试使用 --dry --verbose!)
以下是它提供的命令行选项:
RemoveFromNames_usage.txt
usage: RemoveFromNames.py [-h] [-c] [--dry] [-D] [-F] [-i] [-v] dir remove_string
Process and rename files and directories by removing a specific string.
positional arguments:
dir Input directory to scan recursively
remove_string String to remove from filenames and folder names
options:
-h, --help show this help message and exit
-c, --compress_spaces
Compress multiple spaces into one
--dry Dry run. Do not actually rename anything.
-D, --no_dirs Don't rename directories.
-F, --no_files Don't rename files.
-i, --case_insensitive
Perform case-insensitive compare and replace.
-v, --verbose Print what is being renamed.源代码:
RemoveFromNames.py
#!/usr/bin/env python3
import os
import argparse
def rename_files_in_directory(base_dir, remove_string, compress_spaces=False, dry_run=False, verbose=False, no_dirs=False, no_files=False, case_insensitive=False):
if case_insensitive:
def contains(sub, main):
return sub.lower() in main.lower()
def replace(source, target, string):
pattern = re.compile(re.escape(source), re.IGNORECASE)
return pattern.sub(target, string)
else:
contains = lambda sub, main: sub in main
replace = lambda source, target, string: string.replace(source, target)
# First, rename directories if not skipped by --no_dirs
if not no_dirs:
for dirpath, dirnames, _ in os.walk(base_dir, topdown=False):
for dirname in dirnames:
if contains(remove_string, dirname):
new_name = replace(remove_string, "", dirname)
if compress_spaces:
new_name = ' '.join(new_name.split())
new_name = new_name.strip()
if os.path.exists(os.path.join(dirpath, new_name)):
print(f"Cannot rename directory '{dirname}' to '{new_name}' in '{dirpath}' because a directory with the new name already exists.")
continue
if verbose:
print(f"Renaming directory '{dirname}' to '{new_name}' in '{dirpath}'")
if not dry_run:
os.rename(os.path.join(dirpath, dirname), os.path.join(dirpath, new_name))
# Then, rename files if not skipped by --no_files
if not no_files:
for dirpath, _, filenames in os.walk(base_dir):
for filename in filenames:
if contains(remove_string, filename):
new_name = replace(remove_string, "", filename)
if compress_spaces:
new_name = ' '.join(new_name.split())
new_name = new_name.strip()
if os.path.exists(os.path.join(dirpath, new_name)):
print(f"Cannot rename '{filename}' to '{new_name}' in '{dirpath}' because a file with the new name already exists.")
continue
if verbose:
print(f"Renaming file '{filename}' to '{new_name}' in '{dirpath}'")
if not dry_run:
os.rename(os.path.join(dirpath, filename), os.path.join(dirpath, new_name))
def main():
parser = argparse.ArgumentParser(description="Process and rename files and directories by removing a specific string.")
parser.add_argument("dir", type=str, help="Input directory to scan recursively")
parser.add_argument("remove_string", type=str, help="String to remove from filenames and folder names")
parser.add_argument("-c", "--compress_spaces", action="store_true", help="Compress multiple spaces into one")
parser.add_argument("--dry", action="store_true", help="Dry run. Do not actually rename anything.")
parser.add_argument("-D", "--no_dirs", action="store_true", help="Don't rename directories.")
parser.add_argument("-F", "--no_files", action="store_true", help="Don't rename files.")
parser.add_argument("-i", "--case_insensitive", action="store_true", help="Perform case-insensitive compare and replace.")
parser.add_argument("-v", "--verbose", action="store_true", help="Print what is being renamed.")
args = parser.parse_args()
rename_files_in_directory(args.dir, args.remove_string, args.compress_spaces, args.dry, args.verbose, args.no_dirs, args.no_files, args.case_insensitive)
if __name__ == "__main__":
main()Check out similar posts by category:
Python
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow