Вопрос или проблема
Я пытаюсь скопировать один конкретный файл, который содержится в 960 подкаталогах родительского каталога. Каждый файл имеет одно и то же имя, но уникальное содержимое.
Я хочу сохранить иерархию каталогов и названия в новом родительском каталоге, но мне нужен только один конкретный файл, а не все файлы в каждом подкаталоге.
Мне также нужно создать каждый из этих подкаталогов, названных processorN, где N – это число от 0 до 959.
Какие-либо идеи? Это затрудняет меня, и я не могу найти хорошее решение, которое не займет у меня часы.
rsync
может сделать это с помощью хитрых флагов --include
и --exclude
:
rsync -a -v --include="*/" --include="specific-file.txt" --exclude="*" from/ to/
Это скопирует все каталоги и specific-file.txt
из from
в to
, пропуская все остальное. Команда сохранит полную структуру каталогов ниже from
и скопирует ее в to
. Вы можете сначала запустить это с ключом -n
, чтобы увидеть, что произойдет, то есть:
# проверка:
rsync -a -v -n --include="*/" --include="specific-file.txt" --exclude="*" from/ to/
# фактическое выполнение:
rsync -a -v --include="*/" --include="specific-file.txt" --exclude="*" from/ to/
Я бы просто использовал find и обработал вывод, вот так:
# скопировать все экземпляры имени файла из srcroot в destroot,
# сохраняя структуру каталога
filename="foo.txt"
srcroot="/path/to/src"
destroot="/path/to/dest"
for file in $(find "$srcroot" -name "$filename" -type f -printf "%P\n"); do
path=$(dirname "$file")
mkdir -p "$destroot/$path"
cp -a "$srcroot/$file" "$destroot/$path"
done
Наверняка существуют более быстрые или более изобретательные решения, но это быстро кодировать, легко понять и легко добавить более сложную логику, если это необходимо.
Ответ или решение
Для копирования конкретного файла из множества подкаталогов и сохранения иерархии каталогов в новой директории, можно использовать утилиту find
в сочетании с cp
и mkdir
. Вот решение, которое полностью соответствует вашим требованиям:
- Переменные:
- Задайте переменные для имени файла, корневой директории источника и директории назначения.
filename="specific-file.txt" # Укажите имя вашего файла
srcroot="/путь/к/исходной/директории" # Укажите путь к родительскому каталогу с подкаталогами
destroot="/путь/к/целевой/директории" # Укажите путь к новому родительскому каталогу
- Команда
find
:
Используйтеfind
, чтобы найти все нужные файлы, а затем выполните циклическое копирование:
find "$srcroot" -name "$filename" -type f | while read -r file; do
# Получаем путь относительно корневой директории sources
relpath="${file#$srcroot/}"
# Устанавливаем директорию назначения
destdir="$destroot/$(dirname "$relpath")"
# Создаем подкаталог, если он не существует
mkdir -p "$destdir"
# Копируем файл в назначенную директорию
cp "$file" "$destdir/"
done
Объяснение кода:
find "$srcroot" -name "$filename" -type f
— находит все файлы с заданным именем в указанной директории и её подкаталогах.while read -r file; do ... done
— циклически обрабатывает каждый найденный файл.relpath="${file#$srcroot/}"
— получает относительный путь для создания соответствующей структуры каталогов в новой директории.destdir="$destroot/$(dirname "$relpath")"
— задает путь назначения, включая папку, в которую будет скопирован файл.mkdir -p "$destdir"
— создает необходимую директорию, если она ещё не существует.cp "$file" "$destdir/"
— выполняет копирование найденного файла в целевую директорию.
Возможное использование:
Это решение эффективно и достаточно простое для понимания. Вы можете легко адаптировать его под дополнительные условия, если это потребуется. Если у вас есть другие вопросы или если вам требуется дополнительная помощь, не стесняйтесь обращаться!