it-roy-ru.com

Копировать структуру папок (без файлов) из одного места в другое

Я хочу создать клон структуры нашего многотерабайтного файлового сервера. Я знаю, что cp --parents может перемещать файл и его родительскую структуру, но есть ли способ скопировать структуру каталога без изменений? 

Я хочу скопировать в систему Linux, и наш файловый сервер смонтирован на CIFS.

69
r00fus

Вы могли бы сделать что-то вроде:

find . -type d >dirs.txt

создать список каталогов, затем

xargs mkdir -p <dirs.txt

создать каталоги по назначению.

128
Greg Hewgill
cd /path/to/directories &&
find . -type d -exec mkdir -p -- /path/to/backup/{} \;
63
amphetamachine

Вот простое решение с использованием rsync:

rsync -av -f"+ */" -f"- *" "$source" "$target"
  • одна линия
  • нет проблем с пробелами
  • сохранить разрешения

Я нашел это решение там

19
Gildas

Я не знаю, если вы ищете решение для Linux. Если это так, вы можете попробовать это:

$ mkdir destdir
$ cd sourcedir
$ find . -type d | cpio -pdvm destdir
6
zerodin

Это скопирует каталоги и атрибуты файлов, но не данные файлов:

cp -R --attributes-only SOURCE DEST

Затем вы можете удалить атрибуты файлов, если они вам не интересны:

find DEST -type f -exec rm {} \;
4
toliveira

Это работает:

find ./<SOURCE_DIR>/ -type d | sed 's/\.\/<SOURCE_DIR>//g' | xargs -I {} mkdir -p <DEST_DIR>"/{}"

Просто замените SOURCE_DIR и DEST_DIR.

2
mijhael3000

Замените target_dir и source_dir соответствующими значениями:

cd target_dir && (cd source_dir; find . -type d ! -name .) | xargs -i mkdir -p "{}"

Проверено на OSX + Ubuntu.

1
luissquall

Следующее решение хорошо работает для меня в различных средах:

sourceDir="some/directory"
targetDir="any/other/directory"

find "$sourceDir" -type d | sed -e "s?$sourceDir?$targetDir?" | xargs mkdir -p
1
yaccob

Это решает даже проблему с пробелами:

В оригинальном/исходном каталоге:

find . -type d -exec echo "'{}'" \; > dirs2.txt

затем воссоздайте его во вновь созданном каталоге:

mkdir -p <../<SOURCEDIR>/dirs2.txt
1
Thim

Другой подход заключается в использовании tree, который довольно удобен и перемещается по деревьям каталогов на основе его сильных опций. Есть опции только для каталогов, исключать пустые каталоги, исключать имена с шаблоном, включать только имена с шаблоном и т.д. Проверьте man tree

Преимущество : вы можете редактировать или просматривать список, или если вы делаете много сценариев и часто создаете пакет пустых каталогов

Подход : создать список каталогов, используя tree, использовать этот список в качестве аргумента для ввода mkdir

tree -dfi --noreport > some_dir_file.txt

-dfi перечисляет только каталоги, печатает полный путь для каждого имени, заставляет дерево не печатать строки отступа,

--noreport Позволяет распечатать отчет о файле и каталоге в конце списка дерева, просто чтобы выходной файл не содержал пуха

Затем перейдите к месту назначения, где вы хотите пустые каталоги и выполните

xargs mkdir < some_dir_file.txt
0
brother-bilo

Скрипт Python от Сергея Колодяжного Размещено на Копировать только папки, а не файлы? :

#!/usr/bin/env python
import os,sys
dirs=[ r for r,s,f in os.walk(".") if r != "."]
for i in dirs:
    os.makedirs(os.path.join(sys.argv[1],i)) 

или из оболочки:

python -c 'import os,sys;dirs=[ r for r,s,f in os.walk(".") if r != "."];[os.makedirs(os.path.join(sys.argv[1],i)) for i in dirs]' ~/new_destination

FYI:

0
Franck Dernoncourt

Вот решение в php, которое:

  • копирует каталоги (не рекурсивно, только один уровень)
  • сохраняет разрешения
  • в отличие от решения rsync, работает быстро даже с каталогами, содержащими тысячи файлов, поскольку он даже не попадает в папки
  • не имеет проблем с пробелами
  • должно быть легко читать и настраивать

Создайте файл наподобие syncDirs.php со следующим содержимым:

<?php
foreach (new DirectoryIterator($argv[1]) as $f) {
    if($f->isDot() || !$f->isDir()) continue;
        mkdir($argv[2].'/'.$f->getFilename(), $f->getPerms());
        chown($argv[2].'/'.$f->getFilename(), $f->getOwner());
        chgrp($argv[2].'/'.$f->getFilename(), $f->getGroup());
}

Запустите его как пользователь с достаточными правами:

Sudo php syncDirs.php /var/source /var/destination

0
Christopher K.