Фрагмент Bash для перемещения всех файлов в каталоге в этот каталог


14

У меня есть каталог с большим количеством файлов и каталогов в нем. Чтобы привести это в порядок, я собираюсь поместить все эти файлы в каталог, поэтому я собирался сделать что-то вроде этого:

$ ls | wc -l
123
$ mkdir new_directory
$ mv * ./new_directory

Однако это , очевидно , не будет работать , потому что тогда он будет пытаться двигаться new_directoryв new_directory. Есть ли какой-нибудь простой способ сделать то, что я хочу в одной строке, без необходимости копировать и вставлять все файлы и каталоги в этом каталоге?


3
это работает, он просто печатает сообщение об ошибке, что он не может переместить new_directory в себя.
Cas

Ответы:


18

Ваш

mv * ./new_directory
команда действительно будет работать; он просто выведет предупреждение, что он не может переместить этот каталог в себя.


Единственная проблема в этом состоит в том, что если общее расширение команды становится слишком длинным (то есть слишком много файлов, слишком длинные имена), это больше не будет работать.
Niels Basjes

В качестве примечания: если вы собираетесь сделать это с помощью a, git mvвы должны использовать -kфлаг, так как git по умолчанию завершится с ошибкой, а не просто выдаст предупреждение. Так что вам нужно сделать git mv -k * ./new_dir.
Ювал А

11

Быстрый и грязный вкладыш.

mv `ls -A | grep -v new_directory` ./new_directory

1
Не будет работать: простой ls не будет показывать точечные файлы.
Wzzrd

Очень хороший момент. Исправлено это с -a.

2
Таким образом, вместо того, чтобы пытаться mv new_directory к себе (оригинальный вопрос), вы теперь пытаетесь переместиться. и .. в новый_каталог.
Niels Basjes

2
Спасибо за отзыв, Нильс. Исправлена ​​ошибка с верхним а, который удаляет. и .. из списка каталогов.

8

Если вы просто ищете файлы (т.е. не каталоги), то

find . -type f -maxdepth 1 -exec mv {} ./new_directory/ \;

это самое портативное решение. Для скорости вам следует переместить find и xargs с -print0 и -0, но только если у вас есть GNU find и xargs.


3
Используя сравнительно недавно GNU find, вы также можете использовать \ + вместо \; чтобы уменьшить количество mv, которые мы делаем.
Wzzrd

Если у вас есть GNU find, вы также можете использовать xargs, который будет делать то же самое, и позволит вам запускать несколько mvs одновременно с флагом -p.
Cian

классное использование find- хотя я определенно был на системах, которые не имеют, к сожалению :(
Уоррен

В самом деле? find (afaik) указан в SUS, поэтому все должно иметь его. Единственная проблема заключается в том, является ли это GNU find (которая имеет много хороших интересных опций) или обычная находка.
Cian


6

Когда я столкнулся с этой проблемой, я сделал одно из следующего:

$ mkdir ../new-directory
$ mv * ../new-directory/
$ mv ../new-directory .

или

$ mkdir .new-directory
$ mv * .new-directory/
$ mv .new-directory new-directory

Вторая форма использует преимущества пропуска имен файлов, которые начинаются с '.'


Я забыл пропущенные файлы с точками подстановки; Спасибо за напоминание ! :)
Aemonge

2

как насчет:

cd ..
mv old_dir new_directory
mkdir old_dir
mv new_directory old_dir

Итак, не перемещайте содержимое в новый каталог, но поместите этот каталог в новый.


1

По аналогии с ответом @ Rembrane (хотя и не однострочно):

for FN in *
do
    if [ "<new_dir>" != $FN ] then
        mv $FN <new_dir>
done

Это должно быть на 100% портативно - даже если к findсожалению отсутствует в вашей системе.


find требуется в единой спецификации Unix. Как таковой, он никогда не должен отсутствовать (не то, чтобы вы не могли создать что-то без него. Но я думаю, что это потребует огромных усилий, и ни одна система поставщиков не будет испытывать недостаток в этом)
Cian

может быть, это какой-то гипер-параноидальный сисадмин, yoinking findutils или его эквивалент? не уверен, но я знаю, что столкнулся с боксеном, у которого его нет :(
Уоррен

1

Мои предложения: как заявили другие

mv * ./new_directory

будет работать найти IFF, полное расширение достаточно короткое.

В противном случае вы можете попробовать этот, который масштабируется до гораздо большего числа файлов:

find . -type f -maxdepth 1 | xargs -s100000 echo | xargs -iXXX mv XXX new_directory

объяснение

  1. Список всех файлов.
  2. Сгруппируйте все имена файлов в куски по 100000 символов.
  3. Создайте одну команду mv для каждого чанка.

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

Ты прав. Так что я думаю, что это должно быть дополнено флагами -print0 и -0 для исправления.
Niels Basjes

Я попытался с -print0и -0и это все еще перерывами.
Кристиан Чиупиту

find: warning: вы указали опцию -maxdepth после аргумента-option, не являющегося опцией -type, но опции не позиционные (-maxdepth влияет на тесты, указанные до него, а также на тесты, указанные после него). Пожалуйста, укажите параметры перед другими аргументами.
Кристиан Чиупиту

1

Использование:

find -mindepth 1 -maxdepth 1 \! -name new_directory -print0 | \
    xargs -0 -P 100 -I'{}' mv '{}' new_directory

Со xargsстраницы руководства :

-P max-procs

  Run up to max-procs processes at a time;

-1

Чтобы избежать сообщения об ошибке и сделать его простым:

mv *.* ./new_Folder

будет делать то же самое, но избегать сообщения об ошибке (если у вас нет точек в именах папок, я думаю).

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