Переместить все файлы, кроме одного - PullRequest
129 голосов
/ 22 марта 2009

Как я могу переместить все файлы, кроме одного? Я ищу что-то вроде:

'mv ~/Linux/Old/!Tux.png ~/Linux/New/'

, где я перемещаю старые вещи в новую папку - кроме Tux.png. ! -знак представляет собой отрицание. Есть ли какой-нибудь инструмент для работы?

Ответы [ 13 ]

127 голосов
/ 22 марта 2009

Если вы используете bash и у вас установлена ​​опция оболочки extglob (как это обычно бывает):

mv ~/Linux/Old/!(Tux.png) ~/Linux/New/
85 голосов
/ 25 апреля 2009

Поместите следующее в ваш .bashrc

shopt -s extglob

Расширяет регулярные выражения. Затем вы можете переместить все файлы, кроме одного, на

mv !(fileOne) ~/path/newFolder

Исключения по отношению к другим командам

Обратите внимание, что при копировании каталогов прямая вспышка не может использоваться в имени, как отмечено в потоке Почему extglob, кроме разрыва, кроме условия? :

cp -r !(Backups.backupdb) /home/masi/Documents/

так что Backups.backupdb/ здесь не так до отрицания, и я бы не стал использовать его ни в перемещающихся каталогах из-за риска неправильного использования, а затем с другими командами и возможных других исключений.

66 голосов
/ 22 марта 2009

Я бы пошел с традиционным способом find & xargs:

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png -print0 | 
    xargs -0 mv -t ~/Linux/New

-maxdepth 1 делает поиск не рекурсивным. Если вас интересуют только файлы, вы можете сказать -type f. -mindepth 1 не позволяет включать в результат сам путь ~/Linux/Old. Работает с любыми именами файлов, в том числе с теми, которые содержат символы новой строки.

В одном комментарии отмечается, что опция mv -t является, вероятно, расширением GNU. Для систем, у которых его нет

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png \
    -exec mv '{}' ~/Linux/New \;
20 голосов
/ 22 марта 2009

Быстрый способ - изменить имя файла смокинга, чтобы ваша команда перемещения не соответствовала.

Например:

mv Tux.png .Tux.png

mv * ~/somefolder

mv .Tux.png Tux.png
17 голосов
/ 23 декабря 2016

Я думаю, что самый простой способ сделать это с помощью обратных кавычек

mv `ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

Edit:

Вместо этого используйте обратную косую черту с ls, чтобы не использовать ее с псевдонимом, т. Е. В основном ls имеет псевдоним ls --color.

mv `\ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

Спасибо @Арнольд Роа

13 голосов
/ 22 марта 2009

Для bash sth ответ правильный. Вот синтаксис zsh (мой выбор):

mv ~/Linux/Old/^Tux.png ~/Linux/New/

Требуется установить EXTENDED_GLOB параметр оболочки.

12 голосов
/ 29 апреля 2011

Я считаю, что это немного безопаснее и проще полагаться на простые шаги, исключающие определенные файлы или каталоги.

ls -1 | grep -v ^$EXCLUDE | xargs -I{} mv {} $TARGET
5 голосов
/ 29 марта 2009

Следующий метод не является гарантированным на 100%, и его вообще не следует пытаться использовать в сценариях. Но иногда это достаточно для быстрого использования интерактивной оболочки. Файловый глобус типа

[abc]*

(который будет соответствовать всем файлам с именами, начинающимися с a, b или c), можно отменить, вставив сначала символ «^», т.е.

[^abc]*

Я иногда использую это для несоответствия директории lost + found, например:

mv /mnt/usbdisk/[^l]* /home/user/stuff/.

Конечно, если есть другие файлы, начинающиеся с l, я должен обработать их потом.

4 голосов
/ 22 марта 2009
mv `find Linux/Old '!' -type d | fgrep -v Tux.png` Linux/New

Команда find выводит список всех обычных файлов, а команда fgrep отфильтровывает любой Tux.png. Обратные галочки говорят mv переместить полученный список файлов.

3 голосов
/ 09 января 2019

Как насчет:

mv $(echo * | sed s:Tux.png::g) ~/Linux/New/

Вы должны быть в папке, хотя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...