xargs
est l'outil pour le travail. Que, ou find
avec -exec … {} +
. Ces outils exécutent une commande plusieurs fois, avec autant d'arguments que possible en une fois.
Les deux méthodes sont plus faciles à exécuter lorsque la liste des arguments variables est à la fin, ce qui n'est pas le cas ici: l'argument final mv
est la destination. Avec les utilitaires GNU (c’est-à-dire sur Linux non intégré ou Cygwin), l’ -t
option to mv
est utile, pour transmettre la destination en premier.
Si les noms de fichier ne comportent ni espace ni espace \"'
, vous pouvez simplement fournir les noms de fichier comme entrée xargs
(la echo
commande est une commande intégrée de bash, elle n'est donc pas soumise à la limite de longueur de ligne de commande):
echo !(*.jpg|*.png|*.bmp) | xargs mv -t targetdir
Vous pouvez utiliser l' -0
option pour xargs
utiliser une entrée délimitée par des valeurs NULL au lieu du format cité par défaut.
printf '%s\0' !(*.jpg|*.png|*.bmp) | xargs -0 mv -t targetdir
Alternativement, vous pouvez générer la liste des noms de fichiers avec find
. Pour éviter de rentrer dans les sous-répertoires, utilisez -type d -prune
. Etant donné qu'aucune action n'est spécifiée pour les fichiers image répertoriés, seuls les autres fichiers sont déplacés.
find . -name . -o -type d -prune -o \
-name '*.jpg' -o -name '*.png' -o -name '*.bmp' -o \
-exec mv -t targetdir/ {} +
(Cela inclut les fichiers de points, contrairement aux méthodes génériques du shell.)
Si vous n'avez pas d'utilitaire GNU, vous pouvez utiliser un shell intermédiaire pour obtenir les arguments dans le bon ordre. Cette méthode fonctionne sur tous les systèmes POSIX.
find . -name . -o -type d -prune -o \
-name '*.jpg' -o -name '*.png' -o -name '*.bmp' -o \
-exec sh -c 'mv "$@" "$0"' targetdir/ {} +
Dans zsh, vous pouvez charger le mv
paquet intégré :
setopt extended_glob
zmodload zsh/files
mv -- ^*.(jpg|png|bmp) targetdir/
ou si vous préférez laisser mv
et d'autres noms continuer à faire référence aux commandes externes:
setopt extended_glob
zmodload -Fm zsh/files b:zf_\*
zf_mv -- ^*.(jpg|png|bmp) targetdir/
ou avec des globs de style ksh:
setopt ksh_glob
zmodload -Fm zsh/files b:zf_\*
zf_mv -- !(*.jpg|*.png|*.bmp) targetdir/
Sinon, utilisez GNU mv
et zargs
:
autoload -U zargs
setopt extended_glob
zargs -- ./^*.(jpg|png|bmp) -- mv -t targetdir/