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


14

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

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

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

Ответы:


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 \{} . \;

1

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

mv .. `ls -f | egrep -v '^.$|^..$'

0

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

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.