Переместить каждый файл, который не является каталогом

14

У меня есть каталог, который я пытаюсь очистить, который содержит как файлы, так и подкаталоги. Я пытаюсь сделать все просто: переместить все файлы в другой каталог, но оставить все подкаталоги такими, какие они есть.

Я думаю что-то вроде:

mv [*_but_no_dirs] ./other_directory

Похоже, должен быть простой способ сделать это с помощью символов подстановки *и регулярных выражений ...

У кого-нибудь есть идеи?

Вопросительный знак
источник
1
Итак, переместить все файлы в подпапку, но игнорировать какие-либо в подкаталогах?
Уилф
@ Уилф: Точно.
Вопросительный
2
В zsh вы можете это сделать mv **/*(.) ./other_directory- с bash вам придется прибегать к внешним командам, как find, впрочем.
Godlygeek

Ответы:

12

Регекс не участвуют здесь. Подстановочные знаки в bash (как и большинство других оболочек) соответствуют файлам только на основе имен файлов, а не на основе типа файла или других характеристик. Существует один способ сопоставления по типу: добавление /в конце шаблона позволяет сопоставлять только каталоги или символические ссылки на каталоги. Таким образом, вы можете перемещать каталоги, затем перемещать то, что осталось, и перемещать каталоги назад - громоздко, но это работает.

tmp=$(TMPDIR=.. mktemp -d)
mv -- */ "$tmp"
mv -- * "$tmp"/other_directory/
mv "$tmp"/* .
rmdir "$tmp"

Стандартный способ сопоставления файлов по типу - это вызов find.

find . -name . -o -type d -prune -o -exec sh -c 'mv "$@" "$0"' other_directory/ {} +

В zsh вы можете использовать glob определители для сопоставления файлов по типу. .Отборочные матчи регулярных файлов; используется ^/для сопоставления всех не-каталогов или -^/для включения символических ссылок на каталоги.

mv -- *(.) other_directory/

В любой оболочке вы можете просто зацикливаться.

for x in *; do
   if ! [ -d "$x" ]; then
     mv -- "$x" other_directory/
   fi
done
Жиль "ТАК - перестань быть злым"
источник
8

Вы могли бы использовать что-то вроде

find . -maxdepth 1 \( ! -type d \) -exec sh -c 'mv  "$@" MYDIR' _ {} \;

Сначала мы используем findпоиск только внутри текущего директоя, затем мы игнорируем каталоги, используя, ! -type d наконец, мы выполняем shи перемещаем все в каталог назначения. Вы можете попробовать {} +в конце, который будет быстрее.

Валентин Байрами
источник
2
Немного объяснения, пожалуйста ...
Вопросительный
1
@Questionmark Я обновил ответ и добавил некоторые пояснения. Также стоит посетить mywiki.wooledge.org/UsingFind
Валентин Байрами,
Почему вы предлагаете, -exec sh -c 'mv "$@" MYDIR' _ {} \;а не -exec mv {} MYDIR \;? Просто , чтобы получить что - то , что можно рационализировать путем изменения \;к +? Вы можете сделать это с помощью -exec mv -t MYDIR {} +формы.
Скотт
@ Скотт Я понятия не имел о -tфлаге. Я также объяснил в ответе, что +это быстрее, но не все findверсии поддерживают его. Таким образом, приведенный выше код в значительной степени совместим с любой используемой findоболочкой.
Валентин Байрами
1
@ val0x00ff: «… приведенный выше код в значительной степени совместим с любой используемой findоболочкой или оболочкой». Правда, но так и есть find … -exec mv {} MYDIR \;, и она использует меньше ресурсов, чем … -exec sh -c 'mv "$@" MYDIR' _ {} \;.
Скотт
0

Это потенциально немного опасно, но

cp * destination/
rm *

Поскольку cp и rm не будут работать с каталогами без ключа -r.

miick
источник
-1

Я бы предложил просто сделать mv *.* destination/с пунктом назначения / быть папка, в которую вы перемещаетесь.

Питер Z
источник
2
проверить: unix.stackexchange.com/help/formatting
Джефф Шаллер
2
Имена каталогов могут содержать «точку», а имена файлов могут исключать это (и часто делают), поэтому *.*некоторые каталоги будут перемещены и останутся некоторые файлы, а это не то, чего хотел просящий.
dave_thompson_085
Извините, но это совершенно неправильно. Он просто переместит что-либо с точкой в ​​названии и не переместит ничего без нее. Точки ни в коем случае не являются исключительными для файлов, и они также не требуются для файлов, так что это будет просто перемещать случайный выбор файлов и каталогов.
Тердон
-2
mv $(ls -l | grep "^-" | awk '{print $9}') ./folder_where_move
sy s
источник