Как рекурсивно переместить все файлы (включая скрытые) в подпапке в родительскую папку в *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 в твоей раковине.

Другие вопросы по тегам