Как переместить все файлы из текущего каталога в верхний?
Как переместить все файлы из текущего каталога в верхний в linux?
Я пробовал что-то вроде mv *.*
, но это не работает.
Как переместить все файлы из текущего каталога в верхний в linux?
Я пробовал что-то вроде mv *.*
, но это не работает.
Команда, которую вы ищете, это
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
.
Короткий ответ: используйте
find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +
Длинный ответ:
Команда
mv * .* ..
не будет работать, так как .*
может соответствовать .
и ..
. Но команда
mv * .[^.]* ..
также не будет работать, так как .[^.]*
не будет соответствовать, например, ..filename
! Вместо этого я делаю
mv * .[^.] .??* ..
, который будет соответствовать всему, кроме .
и ..
. *
будет соответствовать всему, что не начинается с .
, .[^.]
будет соответствовать всем 2-символьным именам файлов, начинающимся с точки, кроме ..
, и .??*
будет соответствовать всем именам файлов, начинающимся с точки, состоящей не менее чем из 3-х символов.
Лучше всего использовать
find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +
, что позволяет избежать уродливых взломов глобуса в mv * .[^.] .??* ..
!
В mv отсутствует функциональность перемещения скрытых файлов при использовании *
- так почему бы не использовать копирование вместо этого?
cp -rf . ..
rm -rf *
Не нужно вникать в сложные решения дотглоббирования и использования команд поиска.
rsync -a --remove-source-files . ..
rsync
является чрезвычайно мощным инструментом копирования файлов, обычно используемым для выполнения эффективного инкрементального удаленного резервного копирования и зеркал.
С помощью вышеприведенной команды мы говорим rsync
скопировать содержимое .
в ..
Коммутатор -a
включает рекурсию в подкаталоги .
и включает некоторые другие распространенные опции.
Коммутатор --remove-source-files
говорит rsync удалить исходные файлы после успешной копии, т.е. заставляет rsync вести себя аналогично команде mv
.
Эта минимизированная команда работает на большинстве современных оболочек:
\mv -- {,.{[^.],??}}* ..
Иначе говоря, это портативное решение:
\mv -- * .[^.] .??* ..
Свойства:
\ предотвращает несанкционированное изменение псевдонимов.
– предотвращает интерпретацию имен файлов, содержащих ведущие дефисы (-xyz), в качестве аргументов командной строки.
.[^.] соответствует всем двум именам файлов, начинающимся с . за исключением …
.?* соответствует всем остальным именам файлов, состоящим из трех и более символов.
** Наивные имплементации:**
Ниже пропускаются скрытые имена файлов UNIX, начинающиеся с . (.bashrc).
Следующие совпадают … которые рекурсивно пытаются переместить каждый каталог в конечном итоге обратно в / в … текущего рабочего каталога ($PWD или pwd). Никогда не используйте.
В конце концов, попытка mv .
будет неудачной, потому что mv не сможет удалить каталог, в котором вы в данный момент находитесь. Вы можете mv * ..
переместить файлы в cwd.
Правильнее использовать паттерн * .[!.] .??*
, чем * .[^.] .??*
, так как первый также будет работать со старыми оболочками, такими как ksh88:
mv -- * .[!.] .??* ..
--
предотвращает проблемы, когда у вас есть имя файла, которое начинается с -
*
совпадает со всеми именами файлов, которые не начинаются с .
.
, который вы можете/должны переместить .[!.]
соответствует всем двум именам файлов с символами, которые начинаются с .
.??*
соответствует всем трем именам файлов с символами (или длиннее), которые начинаются с .
С ksh88, шаблон имен файлов .[^.]
на самом деле будет совпадать с именами файлов ..
(которые всегда существуют) и .^
(которых, вероятно, не существует), что приводит к эффекту, противоположному желаемому.
mv * .??* ../.
*
получает все неточечные файлы. .??*
получает все . файлы длиной не менее трех байт, что работает для всех легальных. Все, что осталось, вы, вероятно, захотите, чтобы rm
, а не mv
в любом случае.
../.
не дает никаких прямых преимуществ по сравнению с ..
, но при переходе в каталог это очень хорошая привычка, потому что если что-то не так с путём, то это будет неудачно, как вы хотите, если что-то не так. Например, mv xyz bletch
, где вы think bletch
- каталог, можно сделать более определенным с помощью mv xyz bletch/.
.
Находите и смазывайте тоже. Такая структура может быть полезна, если вы хотите выбирать файлы по более сложным критериям, модифицируя find и egrep.
find -maxdepth 1 | egrep '^./.' # Returns all files
mv `find -maxdepth 1 | egrep '^./.'` .. # mv <all files> ..
Я думаю, что самым простым решением для переноса всех файлов в родительский каталог будет
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
.