Скопіюйте структуру папок (без файлів) з одного місця в інше


94

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

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



Рішення rsync із наведеного вище коментаря виглядає акуратніше.
YE

Відповіді:


158

Ви можете зробити щось на зразок:

find . -type d > dirs.txt

щоб створити список каталогів, потім

xargs mkdir -p < dirs.txt

щоб створити каталоги пункту призначення.


8
Ці рішення не працюватимуть, якщо у ваших назвах каталогів є пробіли.
Jealie

29
@Jealie Змініть команди на find . -type d -print0 >dirs.txtта xargs -0 mkdir -p <dirs.txt. Це призведе до того, що обидві команди використовуватимуть null як роздільники замість пробілів.
user1207177

3
xargsможе перевищувати максимальну довжину команди системи, коли ви починаєте обробляти замовлення в сотні чи тисячі, тому використовуйте це з обережністю. (Знайдіть обмеження довжини команди за допомогою getconf ARG_MAX.) З великою кількістю каталогів, можливо, вам доведеться написати сценарій, щоб замість цього прокрутити вихідні дані.
palswim

1
А як щодо дозволів та атрибутів це буде збережено ??
Ashish Karpe

3
@TrevorBoydSmith: Дякуємо за ваш коментар. В оригінальному запитанні нічого не згадувалося про необхідність зберегти дозволи, право власності чи атрибути. Для цього потрібно, як ви вже згадали, інше рішення, але вищезазначеного достатньо, щоб відповісти на поставлене запитання.
Greg Hewgill

79
cd /path/to/directories &&
find . -type d -exec mkdir -p -- /path/to/backup/{} \;

3
Найкраща відповідь від мене за допомогою find. В іншому випадку ви можете спробувати rsyncрішення від відповіді Чена Леві у цьому СО запитанні
Mat M

3
Що означає варіант - mkdir?
Bruce_Warrior

9
--є стандартним термінатором утиліти GNU. Це означає "ей mkdir, будь-який аргумент після цього, це не прапор, тому трактуйте це як аргумент файлу, навіть якщо він починається з символу" - "."
амфетамахін

4
ця відповідь також не зберігає дозволи та атрибути каталогу . Використовуйте rynsc для збереження дозволів та атрибутів
Тревор Бойд Сміт,

35

Ось просте рішення з використанням rsync:

rsync -av -f"+ */" -f"- *" "$source" "$target"
  • один рядок
  • ніяких проблем з пробілами
  • зберегти дозволи -

Я знайшов це рішення там


10
те саме, але більш читабельнеrsync -a --include '*/' --exclude '*' "$source" "$target"
Sylvain

1
Проблема цього рішення полягає в тому, що мої папки містять тисячі файлів, а rsync потрібен вік, щоб лише синхронізувати десяток папок.
Крістофер К.

6

Не знаю, якщо ви шукаєте рішення на Linux. Якщо так, ви можете спробувати це:

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

cpio, здається, не працює для мене, принаймні з тими параметрами, які ти вказав.
r00fus

@ 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 для справжньої роботи.
тричі

cp -R --attributes-only --preserve = all --parents -v ДЖЕРЕЛО ЗАГУБЛЕННЯ
Габор,

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.


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.


0

Сценарій пітона від Сергія Колодяжного розміщений на " Копіювати лише папки, а не файли?" :

#!/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

Іншим підходом є використання, 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

Рішення в 1 рядок:

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

Дякую, метод 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, і ви не повинні ним користуватися. Але ОП не вказав, хоче він рішення будь-якою конкретною мовою, і, подобається це чи ні, PHP встановлюється все одно на багатьох системах Linux, оскільки 80% Інтернету використовує PHP ( w3techs.com/technologies/details/pl- php / всі / всі ).
Крістофер К.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.