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

185009
Jens Erat

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

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

128
У меня недостаточно репутации, чтобы пометить вопросы, но могу ли я предложить `[linux] [mv] [cwd] [files]` или что-то подобное? Stephan202 14 лет назад 0
Я пометил этот вопрос по запросу Stephan202. eleven81 14 лет назад 0
http://unix.stackexchange.com/a/251091/139312 palindrom 8 лет назад 0

11 ответов на вопрос

196
Stephan202

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

mv * .[^.]* .. 

или (см. ниже для получения дополнительной информации):

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

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

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


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

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

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

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

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

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

Использование `. *` Может привести к тому, что * mv * выдаст предупреждения / ошибки о невозможности перемещения `.` и` ..`. Вместо этого вы можете попробовать `mv *. [^.] * ..`. Chris Johnsen 14 лет назад 7
Очень полный ответ, спасибо. 14 лет назад 0
@alain: пожалуйста, и добро пожаловать на сайт! (Если (и только если) одно из сообщений здесь достаточно ответило на ваш вопрос, то вы можете пометить его как таковое. Это принесет постеру 15 дополнительных очков репутации, а также даст вам 2 дополнительных репутации.) Stephan202 14 лет назад 1
Мне очень нравится шоппинг-решение, работающее в скорлупе :) Paggas 14 лет назад 0
В синтаксисе *. * Нет никакого вреда - в том числе .. опасен только при использовании с chmod и chown и флагом "recurse", т.е. chmod -R или chown -R. И в этих случаях, никогда * никогда * не набирайте chown. * Или chmod. * - выбирайте верхний каталог в пути, который вы ищете, и используйте -h (не переходите по символическим ссылкам). Но, г-н .. просто ничего не делает, так что не беспокойтесь об этом. chris 14 лет назад 2
Это не в состоянии скопировать любые каталоги, которые уже существуют и не являются пустыми в месте назначения. 'mv -f' не помогает. Я не думаю, что есть какой-либо способ форсировать это, поэтому я подозреваю, что мне нужно начать с перебора копируемых файлов и «перезаписать» их из места назначения. Если я делаю это, то я могу также «mv» файлы по одному за раз, повторяя тоже. Jonathan Hartley 12 лет назад 0
Дает mv: переименовать. [^.] * В ../.[^.]*: такого файла или каталога нет pal4life 9 лет назад 0
Работает ли. [^.] * На / bin / sh? jdg 9 лет назад 0
Что делать, если вы находитесь в целевом каталоге? Я использовал это, и это сработало: `mv subdir / (* |. [^.] *) .`. Есть комментарии по этому поводу? Tristan Jahier 9 лет назад 0
у меня не сработало, "mv: not stat`. [^.] * `: нет такого файла или каталога"? centos6 Exlord 8 лет назад 0
Правильные три шаблона: `*`, `. [^.] *` И `..? *`. Второй может быть `. [!.] *` Для более старых (POSIX) оболочек. [Также прочитайте] (http://stackoverflow.com/a/2910105/2350426) 8 лет назад 1
42
Paggas

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

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

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

Команда

mv * .* .. 

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

mv * .[^.]* .. 

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

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

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

А еще лучше, вы можете использовать

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

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

Также я забыл отметить важность - чтобы команда корректно работала с именами файлов, начинающимися с тире. Я включил - в моем ответе найти все же. Более полный ответ с использованием globs: "mv - *. [^.]. ?? * ..". Paggas 14 лет назад 1
+1: я вернулся, чтобы добавить `..? *` К моему комментарию, и вы уже позаботились об этом. Chris Johnsen 14 лет назад 0
Что может быть не так с попыткой mv ..? Он просто ничего не делает и ничего не может сделать. Существуют другие команды, где он * может * что-то сделать (chmod и chown), но mv и rm просто ничего не делают. или же .. chris 14 лет назад 1
Это не работает с папкой .git /; ( Daniel T. Magnusson 11 лет назад 0
Это дает mv: нелегальный вариант - t pal4life 9 лет назад 1
Не могли бы вы объяснить, что делает `- {} +`? Или где я могу найти ответ на этот вопрос? Это единственное волшебство, оставленное мне в этом ответе. Bono 6 лет назад 0
Боно, двойная тире говорит `mv` прекратить поиск дальнейших опций команды. Скобки являются результирующим именем файла. Знак плюс говорит, что вместо запуска exec для каждого результата (т. Е. Для каждого имени файла), поместите как можно больше результатов в один exec, насколько это возможно. Для полноты `-t..` говорит переместить целевой пункт назначения, в который нужно переместить все эти файлы. isuldor 6 лет назад 1
14
Arjan

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

shopt -s dotglob mv -- * .. shopt -u dotglob 
+1. Гораздо чище. Я думаю, что небольшое улучшение в порядке, хотя. Смотрите обновление к моему ответу. Stephan202 14 лет назад 0
8
Micky Martin

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

cp -rf . ..  rm -rf * 

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

__Предупреждение__ Если вы перемещаетесь в файловой системе __same__, в большинстве случаев вы на самом деле не копировали файлы, а только обновляли записи каталога, не перемещая inode или файловые компоненты. Смотрите даже [[1] (http://unix.stackexchange.com/a/48090/66388)]. Вместо `cp` и` rm` вы действительно копируете все. Hastur 8 лет назад 0
6
mrucci
rsync -a --remove-source-files . .. 

rsync is an extremely powerful file copying tool, generally used for performing efficient incremental remote backups and mirrors.

With the above command, we are telling rsync to copy the content of . into ..

The switch -a enables recursion into . subdirectories and enables some other common options.

The switch --remove-source-files tells rsync to remove the source files after a successful copy, i.e. it makes rsync behave similarly to the mv command.

Немного больше объяснений было бы неплохо. ChrisF 11 лет назад 1
Конечно, надеюсь, теперь все понятно. mrucci 11 лет назад 0
Обратите внимание, что `--remove-source-files` не будет удалять (синхронизировать) каталоги. Dennis 10 лет назад 0
Хорошее, принятое решение дает мне ошибку `-bash: / bin / mv: Список аргументов слишком длинный`. Этот работает как шарм. userlond 7 лет назад 0
2
DaveParillo

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

2
DigitalRoss
mv * .??* ../. 

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

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

Вы можете добавить `. [^.]`, Чтобы получить файлы обложки, такие как `.a`. Chris Johnsen 14 лет назад 2
Нет разницы между ../ и ../. так что я бы не стал печатать. после косой черты Кроме того, в случае mv и rm, это не вредно для включения. и ... в списке, то есть нет ничего страшного или неправильного в mv *. * / path / to / file /, как в rm. или даже -rf. ничего не делает chris 14 лет назад 0
2
Barry

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

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

В противном случае упоминается портативное решение:

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

Особенности:

  1. \ предотвращает нежелательное изменение псевдонимов.

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

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

  4. . ?? * соответствует всем другим именам файлов не более трех символов.

Наивные реализации:

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

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

    mv .* .. 
2
jrw32982

It's more correct to use the pattern * .[!.] .??* than * .[^.] .??* since the former will also work with older shells such as ksh88:

mv -- * .[!.] .??* .. 
  • -- prevents problems when you have a file name which begins with -
  • * matches all file names which don't begin with a .
  • there are no one character file names which begin with a . which you can/should move
  • .[!.] matches all two character file names which begin with a .
  • .??* matches all three character file names (or longer) which begin with a .

With ksh88, the file name pattern .[^.] will in fact match the file names .. (which always exists) and .^ (which probably doesn't exist), having an effect opposite to what is desired.

0
user3192145

Find and grep work too. This kind of structure might be helpful if you wanted to select files on more complicated criteria by modifying find and egrep.

find -maxdepth 1 | egrep '^./.' # Returns all files mv `find -maxdepth 1 | egrep '^./.'` .. # mv <all files> .. 

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