2009-10-28 18:54:06 +0000 2009-10-28 18:54:06 +0000
134
134

Как переместить все файлы из текущего каталога в верхний?

Как переместить все файлы из текущего каталога в верхний в linux?

Я пробовал что-то вроде mv *.*, но это не работает.

Ответы (11)

204
204
204
2009-10-28 19:01:58 +0000

Команда, которую вы ищете, это

mv * .[^.]* ..

или (подробнее см. ниже):

(shopt -s dotglob; mv -- * ..)

Пояснение: команда mv перемещает файлы и каталоги. Последним аргументом к команде mv является цель (в данном случае каталог на один шаг “вверх” в дереве, ..). Аргументами перед этим являются исходные файлы и директории. Звездочка (*) - это подстановочный знак, который соответствует всем файлам, не начинающимся с точки. Файлы, которые начинаются с точки (dotfiles), являются “скрытыми”. Они сопоставляются с помощью шаблона .[^.]* (см. редактирование ниже).

Смотрите страницу управления, на которую я дал ссылку, для получения дополнительной информации об mv.


Почему .[^.]* вместо .*?

Как правильно отмечает Крис Джонсен : шаблон .* также совпадает с . и ... Так как вы не хотите (и не можете) перемещать их, лучше использовать шаблон, который совпадает с любым именем файла, начинающимся с точки за исключением этих двух. Шаблон .[^.]* делает именно это: он соответствует любому имени файла (1), начинающемуся с точки (2), за которым следует символ not a dot (3), за которым следует ноль или более произвольных символов.

Так как Paggas указывает на , мы также должны добавить шаблон .??*, чтобы совпасть с файлами, начинающимися с двух точек. Смотрите его ответ на альтернативное решение с использованием find .

Arjan’s ответ упоминает shopt , чтобы избежать всех этих проблем с точечными файлами. Но все же есть проблема с файлами, начинающимися с тире. И для этого требуется три команды. Тем не менее, мне нравится эта идея. Я предлагаю использовать ее вот так:

(shopt -s dotglob; mv -- * ..)

Это выполняет shopt в подоболочке (таким образом, второй вызов shopt не требуется) и использует --, чтобы файлы, начинающиеся с тире, не интерпретировались как аргументы к mv.

45
45
45
2009-10-28 20:19:07 +0000

Короткий ответ: используйте

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

Длинный ответ:

Команда

mv * .* ..

не будет работать, так как .* может соответствовать . и ... Но команда

mv * .[^.]* ..

также не будет работать, так как .[^.]* не будет соответствовать, например, ..filename! Вместо этого я делаю

mv * .[^.] .??* ..

, который будет соответствовать всему, кроме . и ... * будет соответствовать всему, что не начинается с ., .[^.] будет соответствовать всем 2-символьным именам файлов, начинающимся с точки, кроме .., и .??* будет соответствовать всем именам файлов, начинающимся с точки, состоящей не менее чем из 3-х символов.

Лучше всего использовать

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

, что позволяет избежать уродливых взломов глобуса в mv * .[^.] .??* ..!

14
14
14
2009-10-28 20:52:27 +0000

Просто для полноты можно указать оболочке Bash включить скрытые файлы, используя shopt :

shopt -s dotglob
mv -- * ..
shopt -u dotglob
8
8
8
2011-08-02 20:46:48 +0000

В mv отсутствует функциональность перемещения скрытых файлов при использовании * - так почему бы не использовать копирование вместо этого?

cp -rf . ..

rm -rf *

Не нужно вникать в сложные решения дотглоббирования и использования команд поиска.

7
7
7
2013-01-20 11:47:53 +0000
rsync -a --remove-source-files . ..

rsync является чрезвычайно мощным инструментом копирования файлов, обычно используемым для выполнения эффективного инкрементального удаленного резервного копирования и зеркал.

С помощью вышеприведенной команды мы говорим rsync скопировать содержимое . в ..

Коммутатор -a включает рекурсию в подкаталоги . и включает некоторые другие распространенные опции.

Коммутатор --remove-source-files говорит rsync удалить исходные файлы после успешной копии, т.е. заставляет rsync вести себя аналогично команде mv.

2
2
2
2011-08-12 08:12:49 +0000

Эта минимизированная команда работает на большинстве современных оболочек:

\mv -- {,.{[^.],??}}* ..

Иначе говоря, это портативное решение:

\mv -- * .[^.] .??* ..

Свойства:

  1. \ предотвращает несанкционированное изменение псевдонимов.

  2. – предотвращает интерпретацию имен файлов, содержащих ведущие дефисы (-xyz), в качестве аргументов командной строки.

  3. .[^.] соответствует всем двум именам файлов, начинающимся с . за исключением …

  4. .?* соответствует всем остальным именам файлов, состоящим из трех и более символов.

** Наивные имплементации:**

  1. Ниже пропускаются скрытые имена файлов UNIX, начинающиеся с . (.bashrc).

  2. Следующие совпадают … которые рекурсивно пытаются переместить каждый каталог в конечном итоге обратно в / в … текущего рабочего каталога ($PWD или pwd). Никогда не используйте.

2
2
2
2009-10-28 18:59:46 +0000

В конце концов, попытка mv . будет неудачной, потому что mv не сможет удалить каталог, в котором вы в данный момент находитесь. Вы можете mv * .. переместить файлы в cwd.

2
2
2
2013-10-22 22:24:11 +0000

Правильнее использовать паттерн * .[!.] .??*, чем * .[^.] .??*, так как первый также будет работать со старыми оболочками, такими как ksh88:

mv -- * .[!.] .??* ..
  • -- предотвращает проблемы, когда у вас есть имя файла, которое начинается с -
  • * совпадает со всеми именами файлов, которые не начинаются с .
  • нет ни одного имени файла с символами, которые начинаются с ., который вы можете/должны переместить
  • .[!.] соответствует всем двум именам файлов с символами, которые начинаются с .
  • .??* соответствует всем трем именам файлов с символами (или длиннее), которые начинаются с .

С ksh88, шаблон имен файлов .[^.] на самом деле будет совпадать с именами файлов .. (которые всегда существуют) и .^ (которых, вероятно, не существует), что приводит к эффекту, противоположному желаемому.

2
2
2
2009-10-28 19:47:28 +0000
mv * .??* ../.

* получает все неточечные файлы. .??* получает все . файлы длиной не менее трех байт, что работает для всех легальных. Все, что осталось, вы, вероятно, захотите, чтобы rm, а не mv в любом случае.

../. не дает никаких прямых преимуществ по сравнению с .., но при переходе в каталог это очень хорошая привычка, потому что если что-то не так с путём, то это будет неудачно, как вы хотите, если что-то не так. Например, mv xyz bletch, где вы think bletch - каталог, можно сделать более определенным с помощью mv xyz bletch/..

0
0
0
2014-05-12 23:08:11 +0000

Находите и смазывайте тоже. Такая структура может быть полезна, если вы хотите выбирать файлы по более сложным критериям, модифицируя find и egrep.

find -maxdepth 1 | egrep '^./.' # Returns all files

mv `find -maxdepth 1 | egrep '^./.'` .. # mv <all files> ..
0
0
0
2014-08-06 16:37:16 +0000

Я думаю, что самым простым решением для переноса всех файлов в родительский каталог будет

mv "`ls`" ../

или, если есть скрытые файлы/каталоги , то используйте

:

mv "`ls -a`" ../ 2>/dev/null

Также, давайте скажем, что вы хотите переместить содержимое некоторой папки в одну из ее внутренних папок tony(say)

use:

mv "`ls -a`" /tony 2>/dev/null

Заметка:

"`ls -a`"

Чтобы переместить файлы, в которых есть пробелы.

2>/dev/null

Для подавления предупреждения/ошибки, поскольку ls -a также напечатает папки . и .., и вы не сможете их переместить или скопировать. Поэтому для этих папок будет выдана ошибка (если мы не используем 2>/dev/null), что он не может их переместить, а остальные будут перемещены довольно удобно.

Лучше избегать ls -a, если нет скрытых файлов, и просто использовать ls.

Похожие вопросы

6
10
5
37
8