首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过符号链接将多个嵌套目录中的文件合并的脚本

通过符号链接将多个嵌套目录中的文件合并的脚本
EN

Ask Ubuntu用户
提问于 2018-11-30 19:27:23
回答 1查看 1.6K关注 0票数 2

基本上,我正在寻找一个脚本,以自动化的东西(见下图)在Ubuntu。我正在考虑使用bash脚本,但使用其他解决方案(例如。( python?)也会很棒。

1)假设我有许多真正的目录“文件夹1”和“文件夹2”以及子文件夹和文件。假设对应文件夹1和2中的文件具有唯一的名称。如何创建一个新的合并文件夹,其中每个文件都是到原始文件夹的符号链接?

2)脚本还应提供一个选项,以删除合并文件夹中中断的符号链接。

我之所以想这么做,是因为我想改进我的东西的组织方式。例如:“文件夹1\2”可能是在不同的时间点上获得的数据。然后,我会为不同的项目创建Merged_Folder1、Merged_Folder2等,而不会复制大文件。

编辑:这个问题不同于这个职位,因为我想用相同的名称合并相应的嵌套子文件夹。上一篇文章中的问题只是将源下的顶级目录链接到目标,并且不能合并嵌套的子文件夹。注意,在我的例子中,没有一个文件夹是符号链接,只有文件是符号链接。

Edit2:我应该澄清,我希望代码能够合并任意级别的嵌套子文件夹,而不仅仅是两个级别。因此,我在示例示例中添加了"File“和"File”。

EN

回答 1

Ask Ubuntu用户

发布于 2018-12-01 03:31:17

拿到了..。这个python代码应该能够遍历任意数量的嵌套目录,并为合并到目标目录中的文件创建符号链接。参数分别是目标目录和源目录。源目录应该相对于目标dir。例如:

代码语言:javascript
复制
python script.py ./merged_folder ../folder1 ../folder2 ../folder3
代码语言:javascript
复制
import os
import sys
import time
'''
Loops through merge_symlink.
See https://askubuntu.com/questions/1097502/script-for-merging-files-in-multiple-nested-directories-by-symbolic-link/
KH Tam Nov 2018 (matohak)

Use: python merge_symlink.py ./target ../folder1 ../folder2 ../folder3
Note that if overwrite==True and there are duplicated filenames, links will be overwritten by the last argument's
'''

def merge_symlink(sources, overwrite=True, remove_empty_dir=True, verbose=False):
    '''
    See https://askubuntu.com/questions/1097502/script-for-merging-files-in-multiple-nested-directories-by-symbolic-link/
    Function to be run in the target directory.

    :param sources: a list of directories where the files in the subdirectories are to be merged symbolically. Path relative to the target. eg. ["../folder1", "../folder2"]
    :param overwrite: Bool, whether to overwrite existing symbolic links
    :param remove_empty_dir: Bool, whether to remove empty directories in target.
    :param verbose: Prints stuff.
    :return: None
    '''

    # Creating symlinks and folders
    for source in sources:
        for dirName, subdirList, fileList in os.walk(source):
            # print(dirName, fileList)  # print all source dir and files
            if source[-1] == "/": source=source[:-1]

            target_dir = dirName.replace(source, '.', 1)
            depth = dirName.count("/") - source.count("/")

            try:
                os.mkdir(os.path.join(target_dir))
            except FileExistsError:
                pass

            for file in fileList:
                targetlink = os.path.join(target_dir, file)
                try:
                    os.symlink(os.path.join("../"*depth + dirName, file), targetlink)
                except FileExistsError:
                    if overwrite and not (isvalidlink(targetlink)==2):  # Never replace a real file with a symlink!
                        os.remove(targetlink)
                        os.symlink(os.path.join("../" * depth + dirName, file), targetlink)
                        if verbose: print('overwriting {}'.format(targetlink))

    # Pruning broken links and then deleting empty folders.
    for dirName, subdirList, fileList in os.walk("./"):
        for file in fileList:
            link = os.path.join(dirName,file)
            if isvalidlink(link)==0:
                os.remove(link)
                if verbose: print("Removing broken symlink: {}".format(link))

    if remove_empty_dir:
        for dirName, subdirList, fileList in os.walk("./"):
            if fileList==[] and subdirList==[] and dirName!="./":
                os.rmdir(dirName)

# Checks if file is a broken link. 0: broken link; 1: valid link; 2: not a link
def isvalidlink(path):
    if not os.path.islink(path):
        return 2
    try:
        os.stat(path)
    except os.error:
        return 0
    return 1

if __name__ == "__main__":

    target = sys.argv[1]
    sources = sys.argv[2:]      # Inputs should be relative to the target dir.
    overwrite = False
    loop = False
    looptime = 10

    os.chdir(target)
    if not loop:
        merge_symlink(sources, overwrite=overwrite)
    else:
        while loop:
            merge_symlink(sources, overwrite=overwrite)
            time.sleep(looptime)

谢谢@JacobVlijm的链接和@sudodus的帮助!

票数 1
EN
页面原文内容由Ask Ubuntu提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://askubuntu.com/questions/1097502

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档