Копировать только папки, а не файлы?

16

Есть ли способ скопировать весь каталог, но только папки? У меня есть поврежденный файл где-то в моем каталоге, который вызывает сбой моих жестких дисков.

Поэтому вместо того, чтобы копировать поврежденный файл на другой жесткий диск, я хотел просто скопировать папки, потому что у меня есть скрипты, которые ищут сотни папок, и я не хочу создавать их вручную.

Я искал руководство по cp, но ничего не увидел (возможно, я его пропустил)

Скажем, у меня есть эта структура на моем отказавшем жестком диске:

dir1
    files
    dir2
        files
        files
        dir4
dir3
files

Все, что мне нужно, это структура каталогов, а не файлы вообще.

Итак, я бы закончил на новом HDD:

dir1
    dir2
        dir4
dir3

Надеюсь, кто-то знает некоторые хитрости!

Shannon
источник
Вы имеете в виду, что хотите просто скопировать структуру каталогов, или вы просто хотите исключить файлы в текущем рабочем каталоге (а все остальные файлы в более глубоких подкаталогах являются игрой)?
Оли
Я добавил пример. извините за путаницу
Шеннон
1
К сведению, я использую rsyncдля копирования структуры каталогов и сохранения разрешений и атрибутов] ( stackoverflow.com/a/9242883/52074 ). Использование plain mkdir -p не сохраняет разрешений и атрибутов .
Тревор Бойд Смит

Ответы:

15

Если вы хотите отразить каркас каталога и не копировать файлы:

find -type d -links 2 -exec mkdir -p "/path/to/backup/{}" \;

Что тут происходит:

Я сделал это так, а не find -type d -exec mkdir -p "/path/to/backup/{}" \;потому, что это обрезает целую кучу mkdirзвонков. Мы можем быстро доказать это с помощью небольшого теста. Вот дерево тестов, за которым следует то, что я запустил, чтобы сравнить две команды:

$ tree
.
├── dir1
│   ├── dir2
│   │   └── dir3
│   ├── dir7
│   └── dir8
└── dir9
    └── dir0

$ pr -m -t <(find -type d) <(find -type d -links 2)
.                               ./dir1/dir8
./dir1                          ./dir1/dir2/dir3
./dir1/dir8                     ./dir1/dir7
./dir1/dir2                     ./dir9/dir0
./dir1/dir2/dir3
./dir1/dir7
./dir9                  
./dir9/dir0 

И это будет только лучше в реальном решении с тысячами каталогов.

Оли
источник
Это я, нуб, но как вы ищете старый каталог для копирования в резервную копию? Я вижу только один путь здесь
Шеннон,
Если вы не укажете путь, findв качестве отправной точки используется текущий рабочий каталог. Если вы хотите использовать другой путь, используйте синтаксис:find /path/to/search/ -type.....
Oli
Поэтому я установил в своем каталоге определенную папку, содержащую скелет, который я хочу скопировать, запустить, find -type d -exec mkdir -p "/media/jinglez/TVSeries/TV Series"/{}" \;и все должно быть в порядке? Кажется, это займет некоторое время: /
Шеннон
Я запускаю это из обычного терминала, верно?
Шеннон
1
Они оба специфичны для поиска exec-предложения. {} означает текущее «найденное» имя файла и \; это просто побег, чтобы закончить предложение. Судя по всему, в вашем коде есть лишние «до бесполезного, я уверен ... стоит читать:find -type d -links 2 -exec mkdir -p "/media/jinglez/TVSeries/TV Series/{}" \;
Оли
2

Довольно легко сделать с помощью Python One-Liner:

bash-4.3$ tree
.
├── ABC
├── set_pathname_icon.py
├── subdir1
│   ├── file1.abc
│   └── file2.abc
├── subdir2
│   ├── file1.abc
│   └── file2.abc
└── subdir3
    └── subdir4
        └── file1.txt

4 directories, 7 files
bash-4.3$ 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
bash-4.3$ tree ~/new_destination
/home/xieerqi/new_destination
├── subdir1
├── subdir2
└── subdir3
    └── subdir4

Как сценарий это можно переписать так:

#!/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)) 
Сергей Колодяжный
источник