Sposta tutti i file tranne uno


155

Come posso spostare tutti i file tranne uno? Sto cercando qualcosa come:

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

dove sposto roba vecchia in nuova roba -cartella tranne Tux.png. ! -sign rappresenta una negazione. C'è qualche strumento per il lavoro?

Risposte:


142

Se usi bash e hai extglobimpostato l'opzione shell (che di solito è il caso):

mv ~/Linux/Old/!(Tux.png) ~/Linux/New/

1
Ho sbagliato qualcosa quando ho testato il comando per molti elementi: mv ~ / Linux / Old /! (Tux.png Tux1.png Tux2.png) ~ / Linux / New / Svuota l'intera directory Old. Che c'è?
Léo Léopold Hertz

5
@UnixBasics, prova: ~ / Linux / Old /! (Tux.png | Tux1.png | Tux2.png)
Juliano

@Juliano Comando fantastico! Ci sono più operazioni matematiche come OR e XOR? Presumo che una pipe sia per AND.
Léo Léopold Hertz


@Juliano Sono piuttosto confuso di schemi come: mv ~ / Linux /? (Tux * .png) ~ / Linux / New / mv ~ / Linux / + (Tux * .png) ~ / Linux / New / Nel primo , Volevo spostare 0-1 Tux -photo. In quest'ultimo, volevo spostare le foto 1-n Tux. Hanno spostato tutto. Perché? È possibile spostare una determinata quantità di foto?
Léo Léopold Hertz

97

Inserisci quanto segue sul tuo .bashrc

shopt -s extglob

Estende le regex. È quindi possibile spostare tutti i file tranne uno di

mv !(fileOne) ~/path/newFolder

Eccezioni rispetto ad altri comandi

Si noti che, durante la copia delle directory, il forward-flash non può essere usato nel nome come notato nel thread Perché extglob tranne la rottura tranne la condizione? :

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

così Backups.backupdb/è sbagliato qui prima della negazione e non lo userei né per spostare le directory a causa del rischio di usare in modo errato quindi globs con altri comandi e possibili altre eccezioni.


3
Questa è in realtà la risposta corretta. Il mio era completamente sbagliato; per fortuna l'avevo usato in una cartella con solo pochi file. Ecco ulteriori informazioni sul metodo mostrato da Masi: wiki.bash-hackers.org/syntax/pattern Vai a "Linguaggio di modello esteso" e troverai maggiori informazioni al riguardo. Grazie a @ paul-whittaker per aver segnalato il problema.
mimoralea,

Questa è una vecchia risposta ma è ancora valida. Sto usando Ubuntu 18 e extglob sembra essere abilitato di default (non l'ho comprato). Ho usato il seguente comando per spostare tutti i file nella directory corrente in un archivio che si trova anche in questa directory, NON includendo altre cartelle di archivio: mv !(arc*) archive_190629b
TonyG,

70

Vorrei andare con il tradizionale modo find & xargs:

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

-maxdepth 1non fa ricerche ricorsive. Se ti interessano solo i file, puoi dire -type f. -mindepth 1fa in modo che non includa il ~/Linux/Oldpercorso stesso nel risultato. Funziona con qualsiasi nome di file, anche con quelli che contengono newline incorporate.

Un commento osserva che l' -topzione mv è probabilmente un'estensione GNU. Per i sistemi che non ce l'hanno

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png \
    -exec mv '{}' ~/Linux/New \;

1
Eseguito l'upgrade poiché incoraggia l'apprendimento di uno strumento potente, trova. Nota, per i file con spazi bianchi questo non funzionerà. Considera "trova -print0 | xargs -0" oppure rinuncia a xargs: "trova [cosa hai detto] -exec mv -t {} ~ / Linux / New \;"
JasonSmith il

Se il tuo comando mv non ha l'opzione -t, allora usa "trova ... -exec mv {} Linux / New \;" o "trova ... | xargs -I {} mv {} Linux / Nuovo". L'opzione -t sembra essere un'estensione GNU, che va bene per Linux, ma probabilmente non altrove.
Rob Kennedy,

jhs, oh non ci riesco. in qualche modo ho pensato che gli xargs fossero divisi in newline ma non in spazi. sembra che lo abbia confuso con "leggi" :) mal
sistemato

Grazie mille per il fantastico suggerimento! Stavo per scegliere sth perché ha come obiettivo la domanda. Tuttavia, in seguito potrò rilevare l'utilità dei tuoi comandi, quindi devo scegliere il modo "trova e xargs". Oscilla. Grazie :)
Léo Léopold Hertz

Modo complicato. La risposta di Masi è più completa, più semplice e quindi più corretta
user637338

30

Un modo rapido sarebbe quello di modificare il nome del file tux in modo che il comando move non corrisponda.

Per esempio:

mv Tux.png .Tux.png

mv * ~/somefolder

mv .Tux.png Tux.png

non utilizzare " . ", in quanto sposta solo i file con "." nel nome. Basta "*" è sufficiente.
Juliano,

1
Se lo cambi in * rimuoverà anche il tuo file rinominato.
John T

6
@John T: No, il * glob non corrisponde ai file che iniziano con il punto.
Bill Karwin,

Questa è di gran lunga la risposta migliore. Non è necessario modificare o commentare questa risposta. 100 punti. Grazie tante. Molto bene!
Steve K,

23

Penso che il modo più semplice per farlo sia con i backtick

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

Modificare:

Usa invece la barra rovesciata con ls per evitare di usarla con alias, cioè per lo più ls è alias come ls --color.

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

Grazie @Arnold Roa


1
Puoi spiegare perché lo usi grep -vlì?
Léo Léopold Hertz

1
-v L'opzione in grep esclude il risultato, è come prendere tutto tranne Tux.png
Rohail Abbas,

1
Questo è certamente intuitivo, ma le risposte sopra sono migliori. Se stai scrivendo uno script, ad esempio, questo richiederebbe di essere nella directory corretta ..
nJGL

@nJGL Possiamo anche dare un percorso assoluto qui, ho usato homedirectory (~) poiché la domanda aveva questo
Rohail Abbas,

@RohailAbbas Abbastanza giusto. ✌️
nJGL il

14

Per bash, la risposta sth è corretta. Ecco la sintassi di zsh (la mia shell di scelta):

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

Richiede l' EXTENDED_GLOBopzione shell da impostare.


3
E se vogliamo escludere due file?
aprono il

13

Trovo che sia un po 'più sicuro e più facile fare affidamento su semplici mosse che escludono determinati file o directory.

ls -1 | grep -v ^$EXCLUDE | xargs -I{} mv {} $TARGET

Questa è la soluzione migliore per Busybox / ASH
Stuart Cardall

1
Questo ha funzionato per me in una situazione in cui ho dovuto spostare tutti i file tranne poche cartelle in un'altra directory
Umar Hayat

L' -lopzione lsincluderà molte informazioni irrilevanti sulla riga di comando e causerà il fallimento del comando mv.
jdhao,

5

Quanto segue non è un metodo garantito al 100% e non dovrebbe assolutamente essere tentato per lo scripting. Ma a volte è abbastanza buono per un rapido utilizzo interattivo della shell. Un file file glob come

[abc]*

(che corrisponderà a tutti i file con nomi che iniziano con a, b o c) può essere negato inserendo prima un carattere "^", ovvero

[^abc]*

A volte lo uso per non corrispondere alla directory "lost + found", come ad esempio:

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

Naturalmente se ci sono altri file che iniziano con l, devo elaborarli in seguito.


4
mv `find Linux/Old '!' -type d | fgrep -v Tux.png` Linux/New

Il comando find elenca tutti i file regolari e il comando fgrep filtra qualsiasi Tux.png. I backtick indicano a mv di spostare l'elenco di file risultante.


4
Mai e poi mai valutare find come argomenti per un altro comando. Accadranno cose brutte. Potresti aver appena creato una vulnerabilità. Usa sempre find -print0 | xargs -0 costrutto, o trova -exec.
Juliano,

3

Che ne dici di spostare tutto nella cartella e poi semplicemente spostare Tux.png indietro?

Non riesco a pensare a nessuna sintassi della shell che dica "tutto tranne ...


3
ls ~/Linux/Old/ | grep -v Tux.png | xargs -i {} mv ~/Linux/New/'

1
Questo comando sembra mancare di una parte e non funziona sul mio computer. ls ~/Linux/Old/ | grep -v Tux.png | xargs -I{} mv {} ~/Linux/New/funziona invece.
Katherine Chen,

3

Che ne dite di:

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

Devi essere nella cartella però.


3

Si può saltare grep in questo modo:

ls ~/Linux/Old/ -QI Tux.png | xargs -I{} mv ~/Linux/Old/{} ~/Linux/New/

1

Questo potrebbe essere più semplice e facile da ricordare e funziona per me.

mv $(ls ~/folder | grep -v ~/folder/exclude.png) ~/destination

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.