Это, наверное, очень просто, но я не могу понять это. У меня есть такая структура каталогов (dir2 находится внутри dir1):
/dir1
/dir2
|
--- file1
|
--- file2
Каков наилучший способ «сгладить» эту структуру директора таким образом, чтобы получить file1 и file2 в dir1, а не в dir2.
Ответы:
Вы можете сделать это с GNU
find
и GNUmv
:По сути, способ, который работает, если он
find
проходит через все дерево каталогов и для каждого файла (-type f
), который не находится в каталоге верхнего уровня (-mindepth 2
), он запускает,mv
чтобы переместить его в каталог, который вы хотите (-exec mv … +
).-t
Аргументmv
позволяет указать каталог назначения первым, который необходим , потому что+
форма-exec
помещает все места источника в конце команды. В-i
маркеmv
спросить перед перезаписью дубликатов; Вы можете заменить,-f
чтобы перезаписать их, не спрашивая (или-n
не спрашивать или перезаписывать).Как указывает Стефан Чазелас, вышеприведенное работает только с инструментами GNU (стандартными для Linux, но не для большинства других систем). Следующее несколько медленнее (потому что оно вызывается
mv
несколько раз), но гораздо более универсально:источник
-exec +
чтобы оно не выполняло большое количество процессовmv
mv
нужен пункт назначения в качестве последнего аргумента, но + будет иметь источники в качестве последнего аргумента. Find даже не примет синтаксис, который вы изменили на (find: missing argument to `-exec'
)mv
, что-t
мы можем использовать его, так что я его поменяю .find
по умолчанию печатает скрытые (точечные) файлы. Глубина относительно каталога, который вы передаете, чтобы найти.find ./dir -mindepth 2 -type f -exec mv -f '{}' ./dir ';'
если переопределение дубликатовВ зш:
**/
рекурсивно пересекает подкаталоги. Глоба отборочные.
матчи обычных файлов только, иD
гарантирует , что точка файлы включены (по умолчанию, файлы, имя которых начинается с.
исключены из шаблона соответствует). Чтобы потом очистить пустые каталоги, запуститеrmdir dir1/**/*(/Dod)
-/
ограничивает каталоги иod
сначала упорядочивает глубину совпадений, чтобы удалить ихdir1/dir2/dir3
раньшеdir1/dir2
.Если общая длина имен файлов очень велика, вы можете столкнуться с ограничением длины командной строки. Zsh имеет встроенные команды для
mv
иrmdir
которые не страдают от этого ограничения: бежать ,zmodload zsh/files
чтобы включить их.Только с инструментами POSIX:
или (быстрее, потому что не нужно запускать отдельный процесс для каждого файла)
источник
Попробуйте сделать это:
или для каждого файла, соответствующего
file[0-9]*
в subdir:Смотрите http://mywiki.wooledge.org/glob
источник
{}
в моей реальной проблеме.Я написал две функции, которые вы можете использовать вместе, для этого вы можете ограничить уровень каталога, добавив
-maxdepth $VAL
параметр.источник
Расширяя популярный ответ на этот вопрос, поскольку у меня был сценарий использования для выравнивания каталога, содержащего файлы с тем же именем.
В этом случае переданная опция
-i
(--interactive
)mv
не даст желаемого результата, чтобы сгладить структуру каталогов и обработать конфликты имен. Так что это просто заменено на--backup=t
(эквивалентно--backup=numbered
). Дополнительная документация по опции-b
(--backup
) доступна по адресу https://www.gnu.org/software/coreutils/manual/coreutils.html#Backup-options .В результате чего:
Который дает:
источник
tar и zip оба имеют возможность включать, а затем удалять структуру каталогов, поэтому я смог быстро сгладить вложенный каталог с помощью
tar -cvf all.tar *
с последующим перемещением all.tar в новое место, затем
tar -xvf all.tar --strip=4
источник