【问题标题】:Create symbolic links with cp preserving parent structure使用 cp 保留父结构创建符号链接
【发布时间】:2017-11-24 20:21:54
【问题描述】:

我有以下文件夹结构:

.
`-- top_level/
    |-- sub-01_ses-01/
    |   `-- filtered_data.tar.gz*
    |-- sub-01_ses-02/
    |   `-- filtered_data.tar.gz*
    |-- sub-02_ses-01/
    |   `-- filtered_data.tar.gz*
    |-- sub-02_ses-02/
    |   `-- filtered_data.tar.gz*

我想创建指向这些文件的符号链接,保留父结构(因为它们都具有相同的文件名)。 这是我尝试过的:

find -name "filtered_data.tar.gz" \
     -exec cp -s --parents --no-clobber -t /home/data/filtered {} \;

现在,我注意到 cp 确实创建了父结构,但符号链接失败,我收到以下通知:

cp:'/home/data/filtered/./sub-01_ses-01/filtered_data.tar.gz':只能在当前目录建立相对符号链接

我想了解为什么会发生这种情况,以及 cp 警告试图告诉我什么。此外,任何有关如何解决此问题的指示都将不胜感激。

【问题讨论】:

    标签: shell cp


    【解决方案1】:

    在这里找到解决方案:symlink-copying a directory hierarchy

    cp 的文件路径必须是绝对路径,而不是 ./something。所以,这应该适合你:

    find $(pwd) -name "filtered_data.tar.gz" \
         -exec cp -s --parents --no-clobber -t /home/data/filtered {} \;
    

    根据您对您真正想做的事情的评论,这是一个 Python 脚本。你应该可以调整它。

    #!/usr/bin/env python3
    
    import os
    
    target_filename = 'filtered_data.tar.gz'
    top_src_dir = '.'
    top_dest_dir = 'dest'
    
    # Walk the source directory recursively looking for
    # target_filename
    for parent, dirs, files in os.walk(top_src_dir):
        # debugging
        # print(parent, dirs, files)
    
        # Skip this directory if target_filename not found
        if target_filename not in files:
            continue
    
        # Strip off all path parts except the immediate parent
        local_parent = os.path.split(parent)[-1]
        # Compute the full, relative path to the symlink
        dest_file = os.path.join(top_dest_dir, local_parent, target_filename)
    
        # debugging
        # print('{} {}'.format(dest_file, os.path.exists(dest_file)))
    
        # Nothing to do if it already exists
        if os.path.exists(dest_file):
            print('{} already exists'.format(dest_file))
            continue
    
        # Make sure the destination path exists
        dest_dir = os.path.dirname(dest_file)
        os.makedirs(dest_dir, exist_ok=True)
    
        # Translate the relative path to target_filename
        # to be relative based on the new destination dir
        src_file = os.path.join(parent, target_filename)
        src_file = os.path.relpath(src_file, start=dest_dir)
    
        os.symlink(src_file, dest_file)
        print('{} --> {}'.format(dest_file, src_file))
    

    【讨论】:

    • 谢谢,这确实有效,但是我得到了整个父结构!。我只想要从sub-XX_ses-XX开始的结构@
    • 它看起来不像cp 支持它。您可能必须编写脚本或程序(Python 很容易)才能做到这一点。
    猜你喜欢
    • 1970-01-01
    • 2011-10-05
    • 2019-04-18
    • 2013-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-04
    • 1970-01-01
    相关资源
    最近更新 更多