Создать символические ссылки с сохранением cp родительской структуры

У меня есть следующая структура папок:

.
`-- 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 создает родительскую структуру, но символические ссылки не работают, и я получаю следующее уведомление:

ф: '/home/data/filtered/./sub-01_ses-01/filtered_data.tar.gz': может создавать относительные символические ссылки только в текущем каталоге

Я хотел бы понять, почему это происходит, и что cp предупреждение пытается сказать мне. Кроме того, любые указания о том, как решить проблему, будут с благодарностью.

1 ответ

Решение

Нашел решение здесь: symlink-копирование иерархии каталогов

Путь к файлу 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))
Другие вопросы по тегам