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


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.


-1

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



2
Имена каталогов могут содержать «точку», а имена файлов могут исключать это (и часто делают), поэтому *.*некоторые каталоги будут перемещены и останутся некоторые файлы, а это не то, чего хотел просящий.
dave_thompson_085

Извините, но это совершенно неправильно. Он просто переместит что-либо с точкой в ​​названии и не переместит ничего без нее. Точки ни в коем случае не являются исключительными для файлов, и они также не требуются для файлов, так что это будет просто перемещать случайный выбор файлов и каталогов.
Тердон

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