xargsest l'outil pour le travail. Que, ou findavec -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 mvest la destination. Avec les utilitaires GNU (c’est-à-dire sur Linux non intégré ou Cygwin), l’ -toption to mvest 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 echocommande 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' -0option pour xargsutiliser 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 mvpaquet intégré :
setopt extended_glob
zmodload zsh/files
mv -- ^*.(jpg|png|bmp) targetdir/
ou si vous préférez laisser mvet 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 mvet zargs:
autoload -U zargs
setopt extended_glob
zargs -- ./^*.(jpg|png|bmp) -- mv -t targetdir/