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

96

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

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

r00fus
источник
1
Возможный дубликат Rsync, как включать каталоги, но не файлы?
Trevor Boyd Smith
Решение rsync из приведенного выше комментария выглядит аккуратнее.
YE

Ответы:

159

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

find . -type d > dirs.txt

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

xargs mkdir -p < dirs.txt

для создания каталогов в месте назначения.

Грег Хьюгилл
источник
8
Эти решения не будут работать, если в именах каталогов есть пробелы.
Jealie
32
@Jealie Измените команды на find . -type d -print0 >dirs.txtи xargs -0 mkdir -p <dirs.txt. Это заставит обе команды использовать нули в качестве разделителей вместо пробелов.
user1207177 03
3
xargsможет превышать максимальную длину команды системы, когда вы начинаете работать с сотнями или тысячами заказов, поэтому используйте это с осторожностью. (Найдите предел длины команды с помощью getconf ARG_MAX.) При большом количестве каталогов вам, возможно, придется вместо этого написать сценарий для циклического просмотра вывода.
palswim
1
А как насчет разрешений и атрибутов он будет сохранен ??
Ашиш Карпе
3
@TrevorBoydSmith: Спасибо за ваш комментарий. В исходном вопросе ничего не говорилось о необходимости сохранять разрешения, права собственности или атрибуты. Как вы упомянули, для этого потребуется другое решение, но приведенного выше достаточно, чтобы ответить на поставленный вопрос.
Грег Хьюгилл 01
80
cd /path/to/directories &&
find . -type d -exec mkdir -p -- /path/to/backup/{} \;
амфетамашина
источник
3
Лучший ответ от меня с находкой. В противном случае вы можете попробовать rsyncрешение от Чена Леви, ответившего на этот вопрос SO
Mat M
3
Что дает опция - mkdir?
Bruce_Warrior 08
10
--- это терминатор опции стандартной утилиты GNU. Это означает «эй, mkdir, любой аргумент после этого, это не флаг, поэтому рассматривайте его как аргумент файла, даже если он начинается с символа '-'».
amphetamachine
4
этот ответ также не сохраняет разрешения и атрибуты каталога . Используйте rynsc для сохранения разрешений и атрибутов
Тревор Бойд Смит,
36

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

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

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

Gildas
источник
11
то же самое, но более читабельноеrsync -a --include '*/' --exclude '*' "$source" "$target"
Sylvain
1
Проблема с этим решением: мои папки содержат тысячи файлов, а rsync требует времени, чтобы синхронизировать десяток папок.
Christopher K.
6

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

$ mkdir destdir
$ cd sourcedir
$ find . -type d | cpio -pdvm destdir
зеродин
источник
cpio, похоже, у меня не работает, по крайней мере, с указанными вами параметрами.
r00fus 08
@ r00fus - пожалуйста , прочтите руководство по CPIO или обратитесь gnu.org/software/cpio
zerodin
6

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

cp -R --attributes-only SOURCE DEST

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

find DEST -type f -exec rm {} \;
Толивейра
источник
1
Было бы отлично, но вы забыли упомянуть о сохранении прав собственности, отметки времени и разрешений. Таким образом, это вызвало беспорядок в Win7 / cygwin - пользователь NULL_SID, неправильный порядок разрешений, не может редактировать разрешения и т.д. и не может получить доступ к созданной файловой структуре.
WebComer
1
Я думаю, что виноват тот, кто пытается использовать Windows для реальной работы.
Tripleee
cp -R --attributes-only --preserve = all --parents -v ИСТОЧНИК DEST
Габор
2

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

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

find "$sourceDir" -type d | sed -e "s?$sourceDir?$targetDir?" | xargs mkdir -p
яккоб
источник
2

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

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

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

mijhael3000
источник
2

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

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

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

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

mkdir -p <../<SOURCEDIR>/dirs2.txt
Тим
источник
1

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

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

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

Luissquall
источник
0

Скрипт 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

К вашему сведению:

Франк Дернонкур
источник
0

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

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

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

tree -dfi --noreport > some_dir_file.txt

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

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

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

xargs mkdir < some_dir_file.txt
брат-било
источник
0
find source/ -type f  | rsync -a --exclude-from - source/ target/

Копировать каталог только с соответствующим разрешением и владельцем

Тигровый пэн
источник
0

Однострочное решение:

find . -type d -exec mkdir -p /path/to/copy/directory/tree/{} \;
Игорь
источник
-1

Если вы можете получить доступ с компьютера Windows, вы можете использовать xcopy с / T и / E для копирования только структуры папок (/ E включает пустые папки)

http://ss64.com/nt/xcopy.html

[РЕДАКТИРОВАТЬ!]

Здесь используется rsync для воссоздания структуры каталогов, но без файлов. http://psung.blogspot.com/2008/05/copying-directory-trees-with-rsync.html

Может быть лучше :)

доталхимия
источник
1
К сожалению, наш файловый сервер, обслуживающий CIFS, не работает под управлением Windows, поэтому ничего не может сделать с командами win.
r00fus 08
Спасибо, метод rsync у меня отлично сработал. Он также совместим с пробелами в именах каталогов.
Glutanimate
-1

Вот решение на 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

Кристофер К.
источник
Вам не обязательно любить PHP, и вам не обязательно его использовать. Но OP не уточнил, хочет ли он решение на каком-либо конкретном языке, и, нравится ему это или нет, PHP в любом случае установлен во многих системах Linux, поскольку 80% Интернета использует PHP ( w3techs.com/technologies/details/pl- php / все / все ).
Кристофер К.