xargs
è lo strumento per il lavoro. Quello o find
con -exec … {} +
. Questi strumenti eseguono un comando più volte, con tutti gli argomenti che possono essere passati in una volta sola.
Entrambi i metodi sono più facili da eseguire quando l'elenco degli argomenti variabili è alla fine, il che non è il caso qui: l'argomento finale mv
è la destinazione. Con le utility GNU (ovvero su Linux non incorporato o Cygwin), l' -t
opzione mv
è utile per passare prima la destinazione.
Se i nomi dei file non hanno spazi bianchi né alcuno di essi \"'
, puoi semplicemente fornire i nomi dei file come input per xargs
(il echo
comando è incorporato in bash, quindi non è soggetto al limite di lunghezza della riga di comando):
echo !(*.jpg|*.png|*.bmp) | xargs mv -t targetdir
È possibile utilizzare l' -0
opzione per xargs
utilizzare l'input delimitato da null anziché il formato quotato predefinito.
printf '%s\0' !(*.jpg|*.png|*.bmp) | xargs -0 mv -t targetdir
In alternativa, è possibile generare l'elenco di nomi di file con find
. Per evitare di ricorrere in sottodirectory, utilizzare -type d -prune
. Poiché non viene specificata alcuna azione per i file di immagine elencati, vengono spostati solo gli altri file.
find . -name . -o -type d -prune -o \
-name '*.jpg' -o -name '*.png' -o -name '*.bmp' -o \
-exec mv -t targetdir/ {} +
(Ciò include i file di punti, a differenza dei metodi jolly della shell.)
Se non si dispone di utility GNU, è possibile utilizzare una shell intermedia per ottenere gli argomenti nell'ordine giusto. Questo metodo funziona su tutti i sistemi POSIX.
find . -name . -o -type d -prune -o \
-name '*.jpg' -o -name '*.png' -o -name '*.bmp' -o \
-exec sh -c 'mv "$@" "$0"' targetdir/ {} +
In zsh, puoi caricare il mv
builtin :
setopt extended_glob
zmodload zsh/files
mv -- ^*.(jpg|png|bmp) targetdir/
o se si preferisce lasciare mv
e altri nomi continuano a fare riferimento ai comandi esterni:
setopt extended_glob
zmodload -Fm zsh/files b:zf_\*
zf_mv -- ^*.(jpg|png|bmp) targetdir/
o con globs in stile ksh:
setopt ksh_glob
zmodload -Fm zsh/files b:zf_\*
zf_mv -- !(*.jpg|*.png|*.bmp) targetdir/
In alternativa, usando GNU mv
e zargs
:
autoload -U zargs
setopt extended_glob
zargs -- ./^*.(jpg|png|bmp) -- mv -t targetdir/