xargs
это инструмент для работы. Это или find
с -exec … {} +
. Эти инструменты запускают команду несколько раз, используя столько аргументов, сколько можно передать за один раз.
Оба метода проще выполнить, когда список аргументов переменной находится в конце, а здесь это не так: последний аргумент to mv
- это пункт назначения. Для утилит GNU (т. Е. Для не встроенных Linux или Cygwin) полезна -t
опция to mv
, чтобы сначала передать пункт назначения.
Если имена файлов не имеют ни пробелов, ни каких-либо из них \"'
, вы можете просто предоставить имена файлов в качестве входных данных xargs
( echo
команда является встроенной в bash, поэтому она не подпадает под ограничение длины командной строки):
echo !(*.jpg|*.png|*.bmp) | xargs mv -t targetdir
Вы можете использовать -0
опцию, чтобы xargs
использовать ввод с нулем в качестве разделителя вместо формата по умолчанию в кавычках.
printf '%s\0' !(*.jpg|*.png|*.bmp) | xargs -0 mv -t targetdir
Кроме того, вы можете создать список имен файлов с помощью find
. Чтобы избежать повторного использования в подкаталогах, используйте -type d -prune
. Поскольку для перечисленных файлов изображений не указано никаких действий, перемещаются только другие файлы.
find . -name . -o -type d -prune -o \
-name '*.jpg' -o -name '*.png' -o -name '*.bmp' -o \
-exec mv -t targetdir/ {} +
(Это включает файлы точек, в отличие от методов подстановки оболочки.)
Если у вас нет утилит GNU, вы можете использовать промежуточную оболочку, чтобы получить аргументы в правильном порядке. Этот метод работает во всех системах POSIX.
find . -name . -o -type d -prune -o \
-name '*.jpg' -o -name '*.png' -o -name '*.bmp' -o \
-exec sh -c 'mv "$@" "$0"' targetdir/ {} +
В zsh вы можете загрузить mv
встроенное :
setopt extended_glob
zmodload zsh/files
mv -- ^*.(jpg|png|bmp) targetdir/
или если вы предпочитаете, чтобы mv
другие имена продолжали ссылаться на внешние команды:
setopt extended_glob
zmodload -Fm zsh/files b:zf_\*
zf_mv -- ^*.(jpg|png|bmp) targetdir/
или с шариками в стиле ksh:
setopt ksh_glob
zmodload -Fm zsh/files b:zf_\*
zf_mv -- !(*.jpg|*.png|*.bmp) targetdir/
В качестве альтернативы, используя GNU mv
и zargs
:
autoload -U zargs
setopt extended_glob
zargs -- ./^*.(jpg|png|bmp) -- mv -t targetdir/