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


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.