Как рекурсивно переместить все файлы (включая скрытые) в подпапке в родительскую папку в *nix?
Это немного смущающий вопрос, но я должен признать, что в конце моей карьеры у меня все еще есть вопросы о команде mv.
У меня часто возникает эта проблема: мне нужно рекурсивно переместить все файлы на один уровень вверх. Допустим, у меня есть папка foo и панель папок внутри нее. Бар имеет беспорядок файлов и папок, в том числе точечных файлов и папок. Как мне переместить все в баре на уровень foo?
Если foo пусто, я просто перемещаю bar на один уровень выше, удаляю foo и переименовываю bar в foo. Частично проблема заключается в том, что я не могу понять, что такое подстановочный знак mv для "всего, включая точки". Часть этого вопроса заключается в следующем: есть ли подробное обсуждение подстановочных знаков, которые где-то используют команды cp и mv (поиск в Google приводит только к базовым урокам).
6 ответов
В Bash (и некоторых других) вы можете использовать скобки, чтобы выполнить это в одной строке:
mv bar/{,.}* .
Запятая отделяет нуль и точку, поэтому mv
Команда видит имена файлов, которые соответствуют *
а также .*
Этот собирает все файлы из подпапок и перемещает их в текущий каталог
find . -type f -exec mv -iv \{} . \;
Если вы хотите перезаписать файлы с тем же именем, используйте
yes y | find . -type f -exec mv -iv \{} . \;
Самый простой способ сделать это - сделать это двумя командами, потому что * не совпадает.
cd /foo
mv bar/* ./
mv bar/.??* ./
Вы не хотите использовать bar/.*, который я обнаружил при совершении этой ошибки:
rm -rf ./.*
Это плохая вещь. Кто-нибудь хочет угадать, почему?;-)
Первое, что нужно знать о глобализации, - это делает оболочка, а не команда. Проверьте man-страницу вашей оболочки для всех деталей.
mv .??* *
позаботится обо всем, кроме точки, за которой следует один символ. Если это характерно для вашей ситуации, вы можете добавить .[a-zA-Z0-9]*
, Это по-прежнему оставляет файлы с такими именами, как .;
, .^
, а также .^I
(Вкладка). Если вам нужно справиться со всем, вам нужно быть немного сложнее.
mv .. `ls -f | egrep -v '^.$|^..$'
Если у вас есть структура каталогов /foo/bar/
и вы хотите переместить все файлы в bar
на шаг выше, зайдите в bar
каталог и введите следующее:
find . -depth -print0 | cpio --null -pvd ../
Вообще я думаю cpio(1)
лучше для такого рода задач. Вы можете проверить подробную документацию, выдав info cpio
в твоей раковине.