Назад | Перейти на главную страницу

Как рекурсивно переместить все файлы (в том числе скрытые) из подпапки в родительскую папку в * nix?

Это немного неловкий вопрос, но я должен признать, что в конце моей карьеры у меня все еще есть вопросы по команде mv.

У меня часто возникает такая проблема: мне нужно рекурсивно переместить все файлы на один уровень выше. Скажем, у меня есть папка foo и панель папок внутри нее. Бар содержит множество файлов и папок, в том числе точечные файлы и папки. Как мне переместить все в bar на уровень foo?

Если foo пусто, я просто перемещаю bar на один уровень выше, удаляю foo и переименовываю bar в foo. Отчасти проблема в том, что я не могу понять, что такое подстановочный знак mv для «всего, включая точки». Часть этого вопроса заключается в следующем - есть ли подробное обсуждение подстановочных знаков, которые команды cp и mv где-то используют (поиск в Google дает только очень простые учебники).

В Bash (и некоторых других) вы можете использовать расширение фигурных скобок, чтобы выполнить это в одной строке:

mv bar/{,.}* .

Запятая разделяет нуль и точку, поэтому mv команда видит имена файлов, которые совпадают * и .*

Он собирает все файлы из подпапок и перемещает их в текущий каталог.

find . -type f -exec mv -iv \{} . \;

Если вы хотите перезаписать файлы с тем же именем, используйте

yes y | find . -type f -exec mv -iv \{} . \;

Самый простой способ сделать это - использовать две команды, потому что * не соответствует .whatever

cd /foo
mv bar/* ./
mv bar/.??* ./

Вы не хотите использовать bar /.*, о котором я узнал при совершении этой ошибки:

rm -rf ./.* 

Это ПЛОХО. Кто-нибудь хочет угадать, почему? ;-)

Первое, что нужно знать о подстановке - это выполняется оболочкой, а не командой. Проверьте все подробности на странице руководства вашей оболочки.

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 в вашей оболочке.