import os
import shutil
def should_skip_path(src_path, dst_dir, skip_dir_names=None):
"""
检查是否应该跳过给定的路径。
参数:
- src_path: 当前正在考虑复制的源路径。
- dst_dir: 目标目录路径。
- skip_dir_names: 需要跳过的子目录名称列表。
返回:
- 布尔值,True表示应该跳过,False表示不应该。
"""
# 转换为绝对路径进行比较
abs_src_path = os.path.abspath(src_path)
abs_dst_dir = os.path.abspath(dst_dir)
# 检查目标目录是否以当前源路径为基路径
if abs_dst_dir.startswith(abs_src_path):
return True
# 如果指定了需要跳过的目录名,检查当前路径是否包含这些目录
if skip_dir_names:
for skip_dir_name in skip_dir_names:
# 检查目录名是否在路径中
if skip_dir_name in src_path.split(os.sep):
return True
return False
def copy_script_files(src_dir, dst_dir, skip_dir_names=None, extensions=('.sh', '.ipynb', '.py')):
"""
复制目录结构并仅保留指定后缀的脚本文件。
参数:
- src_dir: 源目录路径。
- dst_dir: 目标目录路径。
- skip_dir_names: 不希望复制的子目录名称列表。
- extensions: 要保留的文件后缀元组。
"""
if not os.path.exists(dst_dir):
os.makedirs(dst_dir)
for root, dirs, files in os.walk(src_dir):
# 动态修改dirs列表,跳过不需要的子目录
dirs[:] = [d for d in dirs if not should_skip_path(os.path.join(root, d), dst_dir, skip_dir_names)]
for dir in dirs:
src_path = os.path.join(root, dir)
dst_path = src_path.replace(src_dir, dst_dir, 1)
if not os.path.exists(dst_path):
os.makedirs(dst_path)
for file in files:
if file.endswith(extensions):
src_file_path = os.path.join(root, file)
dst_file_path = src_file_path.replace(src_dir, dst_dir, 1)
if not should_skip_path(src_file_path, dst_dir, skip_dir_names):
shutil.copy2(src_file_path, dst_file_path)
# 指定源目录和目标目录
src_directory = '/data1/username'
dst_directory = '/data1/username/username_copy'
# 指定跳过的子目录列表
skip_directory_names = ['0030.software', 'genomes', 'genome_fasta', 'geo_meta', 'reference']
# 调用函数
copy_script_files(src_directory, dst_directory, skip_directory_names)
这个代码解决了,尽管新的目标目录在原目录下,也很好的跳过处理,
并且设置了跳过处理的目录的功能,例如有的目录下只有数据文件,或者是一个conda环境目录,我们就不需要复制其中的sh脚本等。 |