生信人

找回密码
立即注册
搜索
热搜: 活动 交友 discuz
发新帖

0

收听

12

听众

318

主题
发表于 2024-4-18 13:06:36 | 查看: 30697| 回复: 2

背景

之前写的脚本和数据文件都混合在同一级目录中,因为文件夹过于庞大,一个一个整理实在耗费时间,所以想使用脚本判断属于脚本的单独复制到新的目录,同时保持目前的目录结构。

解决方案

使用python,代码如下:

import os
import shutil

def copy_script_files(src_dir, dst_dir, extensions=('.sh', '.ipynb', '.py')):
    """
    复制目录结构并仅保留指定后缀的脚本文件。

    参数:
    - src_dir: 源目录路径。
    - dst_dir: 目标目录路径。
    - extensions: 要保留的文件后缀元组。
    """
    # 确保目标目录存在
    os.makedirs(dst_dir, exist_ok=True)

    # 遍历源目录
    for root, dirs, files in os.walk(src_dir):
        # 重建目录结构
        for dir in dirs:
            src_path = os.path.join(root, dir)
            dst_path = src_path.replace(src_dir, dst_dir, 1)
            os.makedirs(dst_path, exist_ok=True)

        # 复制符合条件的文件
        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)
                shutil.copy2(src_file_path, dst_file_path)

# 指定源目录和目标目录
src_directory = '/data1/username'
dst_directory = '/data1/username/username_copy'

# 调用函数
copy_script_files(src_directory, dst_directory)

以上代码复制了 指定后缀的脚本文件,并移动到新的目录,且保持目录结构一致。

后记

在数据分析中,我们最好是将数据和脚本文件分开不同的路径存储,这样可以分开备份数据和脚本,并且保持目录整洁。

收藏回复 显示全部楼层 道具 举报

发表于 2024-4-18 15:14:45

以上代码存在一个问题,即

# 指定源目录和目标目录
src_directory = '/data1/username'
dst_directory = '/data1/username/username_copy'

这两个路径需要是独立的,不然会一直循环复制下去即会产生

/data1/username/username_copy/username_copy/username_copy/username_copy/username_copy

这个问题需要注意。

下面更新一个修改版的代码。

回复 显示全部楼层 道具 举报

发表于 2024-4-18 15:17:04
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脚本等。

回复 显示全部楼层 道具 举报

您需要登录后才可以回帖 登录 | 立即注册

QQ|Archiver|手机版|小黑屋|生信人 ( 萌ICP备20244422号 )

GMT+8, 2024-11-23 17:32 , Processed in 0.078512 second(s), 32 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表