it-swarm-eu.dev

Come spostare tutti i file dalla directory corrente alla directory superiore?

Come spostare tutti i file dalla directory corrente alla directory superiore in linux?

Ho provato qualcosa come mv *.*, ma non funziona.

131
asksuperuser

Il comando che stai cercando è

mv * .[^.]* ..

oppure (vedi sotto per maggiori informazioni):

(shopt -s dotglob; mv -- * ..)

Spiegazione: il comando mv sposta i file e le directory. L'ultimo argomento per mv è il target (in questo caso la directory un passo "su" nell'albero, ..). Gli argomenti precedenti sono i file e le directory di origine. L'asterisco (*) è un carattere jolly che corrisponde a tutti i file che non iniziano con un punto. I file che iniziano con un punto (dotfile) sono "nascosti". Sono abbinati usando lo schema .[^.]* (vedi modifica sotto).

Vedi la manpage che ho linkato per maggiori informazioni su mv.


Perché .[^.]* anziché .*?

Come Chris Johnsen indica correttamente: il pattern .* corrisponde anche a . e ... Dato che non vuoi (e non puoi) spostarli, è meglio usare un pattern che corrisponda a qualsiasi nome di file che inizia con un punto eccetto questi due. Il pattern .[^.]* fa proprio questo: corrisponde a qualsiasi nome di file (1) che inizia con un punto (2) seguito da un carattere che è not un punto (3) seguito da zero o più caratteri arbitrari.

Come Paggasindica , dovremmo anche aggiungere il pattern .??* per abbinare i file che iniziano con due punti. Vedi la sua risposta per una soluzione alternativa usando find .

Arjan's answer menzioni shopt per evitare tutti quei problemi con dotfiles. Ma poi c'è ancora il problema con i file che iniziano con un trattino. E richiede tre comandi. Comunque, mi piace l'idea. Propongo di usarlo in questo modo:

(shopt -s dotglob; mv -- * ..)

Questo esegue shopt in una subshell (quindi nessuna seconda chiamata a shopt required) e usa -- in modo che i file che iniziano con un trattino non vengano interpretati come argomenti a mv.

199
Stephan202

Risposta breve: usare

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

Risposta lunga:

Il comando

mv * .* ..

non funzionerà poiché .* può corrispondere a . e ... Ma il comando

mv * .[^.]* ..

non funzionerà, poiché .[^.]* non corrisponderà, ad es. ..filename! Invece, quello che faccio è

mv * .[^.] .??* ..

che corrisponderà a tutto tranne . e ... * corrisponderà a tutto ciò che non inizia con ., .[^.] corrisponderà a tutti i nomi di file di 2 che iniziano con un punto tranne .., e .??* corrisponderà a tutti i nomi di file che iniziano con un punto con almeno 3 caratteri.

Meglio ancora, puoi usare

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

che evita i brutti attacchi di glob in mv * .[^.] .??* ..!

42
Paggas

Solo per completezza, si può anche dire alla Bash Shell di includere i file nascosti, usando shopt :

shopt -s dotglob
mv -- * ..
shopt -u dotglob
14
Arjan

Il mv non ha la funzionalità di spostare i file nascosti quando si utilizza * - quindi perché non usare invece la copia?

cp -rf . ..

rm -rf *

Non è necessario entrare in soluzioni complesse di dotglobbing e utilizzare i comandi di ricerca.

8
Micky Martin
rsync -a --remove-source-files . ..

rsync è uno strumento di copia di file estremamente potente, generalmente utilizzato per l'esecuzione di efficienti backup e mirror incrementali remoti.

Con il comando precedente, stiamo dicendo a rsync di copiare il contenuto di . in ..

Lo switch -a abilita la ricorsione nelle sottodirectory . e abilita alcune altre opzioni comuni.

Lo switch --remove-source-files indica a rsync di rimuovere i file di origine dopo una copia riuscita, vale a dire che rsync si comporta in modo simile al comando mv.

6
mrucci

È più corretto utilizzare il pattern * .[!.] .??* di * .[^.] .??* poiché il primo funzionerà anche con shell meno recenti come ksh88:

mv -- * .[!.] .??* ..
  • -- impedisce problemi quando si ha un nome di file che inizia con -
  • * corrisponde a tutti i nomi di file che non iniziano con .
  • non ci sono nomi di file di un carattere che iniziano con un . che puoi/dovresti spostare
  • .[!.] corrisponde a tutti e due i nomi dei file dei caratteri che iniziano con .
  • .??* corrisponde a tutti e tre i nomi dei file dei caratteri (o più) che iniziano con un .

Con ksh88, il pattern name .[^.] corrisponderà di fatto ai nomi di file .. (che esiste sempre) e .^ (che probabilmente non esiste), con un effetto opposto a quello desiderato.

2
jrw32982

Questo comando minimizzato funziona sulla maggior parte delle shell moderne:

\mv -- {,.{[^.],??}}* ..

Altrimenti citato è una soluzione portatile:

\mv -- * .[^.] .??* ..

Caratteristiche:

  1. \ impedisce agli alias di alterare mv in modo indesiderato.

  2. - impedisce che i nomi file contenenti trattini iniziali (-xyz) vengano interpretati come argomenti della riga di comando.

  3. . [^.] corrisponde a tutti e due i nomi di file che iniziano con. eccetto ..

  4. . ?? * corrisponde a tutti gli altri nomi di file di tre caratteri o più.

Implementazioni Naive:

  1. Il seguente ignora i nomi di file UNIX nascosti, quelli che iniziano con. (.Bashrc).

    mv * ..
    
  2. Le seguenti corrispondenze .. che in modo ricorsivo tenta di spostare tutte le directory alla fine fino a/in .. della directory di lavoro corrente ($ PWD o pwd). Non usare mai.

    mv .* ..
    
2
dhchdhd

In definitiva, provare mv . fallirà perché mv non sarà in grado di scollegare la directory in cui ci si trova attualmente. Si potrebbe mv * .. per spostare i file nella cwd.

2
DaveParillo
mv * .??* ../.

* ottiene tutti i file non puntati. .??* ottiene tutto. file di almeno tre byte, che funziona per tutti quelli legittimi. Qualunque cosa lasci probabilmente vorrà rm piuttosto che mv.

Il ../. non offre alcun vantaggio diretto su .. ma quando si fa un move-to-directory è una buona abitudine entrare, perché fallirà, come si vuole, se c'è qualcosa di sbagliato nel percorso. Ad esempio, mv xyz bletch, in cui think bletch è una directory, può essere reso più sicuro con mv xyz bletch/..

2
DigitalRoss

Trova e anche grep lavora. Questo tipo di struttura potrebbe essere utile se si desidera selezionare i file su criteri più complicati modificando find e egrep.

find -maxdepth 1 | egrep '^./.'         # Returns all files

mv `find -maxdepth 1 | egrep '^./.'` .. # mv <all files> ..
0
user3192145

Penso che la soluzione più semplice per spostare tutti i file nella directory principale. sarebbe

mv "`ls`" ../

o, se ci sono file/directory nascosti

uso:

mv "`ls -a`" ../ 2>/dev/null

Inoltre, diciamo che vuoi spostare il contenuto di alcune cartelle in una delle sue cartelle interne tony (diciamo)

uso:

mv "`ls -a`" /tony 2>/dev/null

Nota:

"`ls -a`" 

Per spostare i file che contengono spazi.

2>/dev/null

È per sopprimere l'avviso/errore perché ls -a dovrebbe stampare anche la cartella . e .. e non è possibile spostarli o copiarli. Quindi per quelle cartelle mostrerà l'errore (se non usiamo 2>/dev/null) che non può spostarle e il resto verrà spostato abbastanza comodamente.

Meglio evitare ls -a se non ci sono file nascosti e basta usare ls.

0