Изящный путь использовал бы richacls. Но это еще не торжественная часть ядра и таким образом может быть трудно использовать для Вас.
Легкое обходное решение должно было бы использовать параметры самбы directory mask
и force directory security mode
представлять недавно созданные каталоги, бесполезные (недоступный) пользователям так, чтобы они учились не создавать каталоги.
Забавное (и портативный!) путь состоял бы в том, чтобы создать столько (невидимых) подкаталогов, что предел подкаталога файловой системы достигнут. Если бы новый подкаталог необходим, администратор просто переименовал бы одного из них.
Другой вариант (который может быть более портативным) -
cd source_directory find . -type f -print0 | cpio --pass-through --null --link --make-directories dest_dir
cpio
(копирование и извлечение) - динозавр, предшествующий tar
.
Подобно tar
, он может создавать или извлекать из архивов.
В отличие от tar
(поправьте меня, если я ошибаюсь),
он может копировать деревья каталогов с помощью одной команды.
(Я думаю, вы могли бы сделать это с помощью tar -cf - исходных параметров и аргументов | tar -xf - параметров назначения и аргументов)
.)
Вот что означает - сквозной
.
- null
означает «ожидать, что имена файлов будут разделены нулями»;
т.е. читать вывод из find… -print0
.
- ссылка
означает «связать файлы из исходного каталога в целевой каталог,
если возможно".
- make-каталоги
в пояснениях не нуждаются.
Это может быть сокращено cpio –p0ld dest_dir
.
Добавьте - подробный
или -v
, если хотите.
Затем, после того, как это закончится,
Вы можете использовать prename
, чтобы получить то, что хотите. В некоторых дистрибутивах (например, Debian / Ubuntu) он должен быть установлен по умолчанию и иметь псевдоним переименовать
. Другие дистрибутивы могут использовать другое переименование
. Вы можете перейти в каталог над исходным каталогом и сделать:
find source -exec prename 's:^source:/path/to/dest:' {} +
Это откажется от перемещения файлов, которые уже существуют в целевом дереве, и оставит пустые каталоги в случае, если имена каталогов перекрываются, поэтому вы сможете удалить их после . Вы можете добавить параметр -f
к prename
, чтобы он перезаписывал существующие файлы.
Пример:
$ mkdir -p dir1/{common,sub1} dir2/{common,sub2}
$ touch dir1/sub1/file dir2/sub2/file dir1/common/common dir2/common/common dir1/common/diff1 dir2/common/diff2
$ tree dir*
dir1
├── common
│ ├── common
│ └── diff1
└── sub1
└── file
dir2
├── common
│ ├── common
│ └── diff2
└── sub2
└── file
4 directories, 6 files
$ find dir2 -depth -exec rename 's/^dir2/dir1/' {} +
Can't rename dir2/sub2/file dir1/sub2/file: No such file or directory
dir2/common/common not renamed: dir1/common/common already exists
dir2/common not renamed: dir1/common already exists
dir2 not renamed: dir1 already exists
$ tree dir*
dir1
├── common
│ ├── common
│ ├── diff1
│ └── diff2
├── sub1
│ └── file
└── sub2
└── file
dir2
└── common
└── common
4 directories, 6 files
Обновление:
Чтобы предоставить исходный код для prename
, он обычно поставляется в комплекте с perl
(отсюда и «p»). В Debian / Ubuntu он является частью пакета perl
. Если вы хотите получить его отдельно, один из ответивших на этот вопрос - Получить утилиту переименования Perl вместо встроенного переименования сделал для нее отдельный репозиторий - https: // github .com / subogero / rename