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

14

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

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

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

deadprogrammer
источник

Ответы:

19

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

mv bar/{,.}* .

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

Приостановлено до дальнейшего уведомления.
источник
это попытка переместить '..' также, терпит неудачу с сообщением 'ресурс занят'. Тем не менее работает.
Ксананакс
3
Предложил анонимный пользователь:To eliminate the error caused by also matching "." and "..", use this command: mv bar/{,.[!.],..?}* .
HopelessN00b
2

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

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

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

rm -rf ./.* 

Это плохая вещь. Кто-нибудь хочет угадать, почему? ;-)

Мэтт Симмонс
источник
Я не думаю, что Bash или Zsh расширяются .*до .и ... Zsh не для меня по крайней мере.
Микаэль С
Микаэль: Я могу пообещать, что bash делает (или, по крайней мере, делал), так как мне пришлось восстанавливать пользовательские каталоги, которые я уничтожил, делая это
Мэтт Симмонс,
2

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

Джефф Лейзер
источник
2

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

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

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

yes y | find . -type f -exec mv -iv \{} . \;
michelek
источник
1

mv .??* *позаботится обо всем, кроме точки, за которой следует один символ. Если это характерно для вашей ситуации, вы можете добавить .[a-zA-Z0-9]*. Это будет по- прежнему оставить файлы с такими именами, как .;, .^и .^I(вкладка). Если вам нужно справиться со всем, вам нужно быть немного сложнее.

mv .. `ls -f | egrep -v '^.$|^..$'
mpez0
источник
0

Если у вас есть структура каталогов, /foo/bar/и вы хотите переместить все файлы на barодин шаг выше, перейдите в barкаталог и введите следующее:

find . -depth -print0 | cpio --null -pvd ../

Вообще, я думаю, что cpio(1)лучше для такого рода задач. Вы можете проверить подробную документацию, выпустив info cpioв вашей оболочке.

FIM
источник