使用 cp 保留父结构创建符号链接
Create symbolic links with cp preserving parent structure
我有以下文件夹结构:
.
`-- 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'
: can make relative symbolic links only in current directory
我想了解为什么会发生这种情况,以及 cp
警告试图告诉我什么。此外,将不胜感激有关如何解决该问题的任何指示。
在此处找到解决方案: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))
我有以下文件夹结构:
.
`-- 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'
: can make relative symbolic links only in current directory
我想了解为什么会发生这种情况,以及 cp
警告试图告诉我什么。此外,将不胜感激有关如何解决该问题的任何指示。
在此处找到解决方案: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))