Создать символические ссылки с сохранением 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))