2009-10-28 18:54:06 +0000 2009-10-28 18:54:06 +0000
134
134

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.

Risposte (11)

204
204
204
2009-10-28 19:01:58 +0000

Il comando che stai cercando è

mv * .[^.]* ..

oppure (vedi sotto per maggiori informazioni):

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

Spiegazione: il comando mv sposta file e directory. L'ultimo argomento di mv è la destinazione (in questo caso la directory un passo “su” nell'albero, ..). Gli argomenti che lo precedono 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 (dotfiles) sono “nascosti”. Vengono abbinati usando lo schema .[^.]* (vedi modifica sotto).

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


Perché .[^.]* invece di .*?

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

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

La risposta di Arjan menziona shopt per evitare tutti quei problemi con i 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 richiesta) e usa -- in modo che i file che iniziano con un trattino non siano interpretati come argomenti di mv.

45
45
45
2009-10-28 20:19:07 +0000

Risposta breve: usa

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

Risposta lunga:

Il comando

mv * .* ..

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

mv * .[^.]* ..

non funzionerà, poiché .[^.]* non corrisponderà, per esempio, a ..filename! Invece, quello che faccio è

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

che corrisponderà a tutto tranne a . e ... * corrisponderà a tutto ciò che non inizia con un ., .[^.] corrisponderà a tutti i nomi di file di 2 caratteri 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 hack glob in mv * .[^.] .??* ..!

14
14
14
2009-10-28 20:52:27 +0000

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

shopt -s dotglob
mv -- * ..
shopt -u dotglob
8
8
8
2011-08-02 20:46:48 +0000

Il mv manca della funzionalità di spostare file nascosti quando si usa * - quindi perché non usare invece copy?

cp -rf . ..

rm -rf *

Non c'è bisogno di addentrarsi in complesse soluzioni di dotglobbing e di usare i comandi find.

7
7
7
2013-01-20 11:47:53 +0000
rsync -a --remove-source-files . ..

rsync è uno strumento di copia di file estremamente potente, generalmente usato per eseguire efficienti backup incrementali remoti e mirror.

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 dice a rsync di rimuovere i file sorgente dopo una copia riuscita, cioè fa sì che rsync si comporti in modo simile al comando mv.

2
2
2
2011-08-12 08:12:49 +0000

Questo comando minimizzato funziona sulla maggior parte delle shell moderne:

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

Altrimenti è una soluzione portatile:

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

Caratteristiche:

  1. \ 1. Previene che gli alias alterino mv in modo indesiderato.

  2. – impedisce che nomi di file contenenti trattini iniziali (-xyz) siano interpretati come argomenti della linea di comando.

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

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

** Implementazioni ingenue:**

  1. La seguente salta i nomi di file UNIX nascosti, quelli che iniziano con . (.bashrc).

  2. Il seguente corrisponde a .. che tenta ricorsivamente di spostare ogni directory eventualmente fino a / in .. della directory di lavoro corrente ($PWD o pwd). **Non usare mai.

2
2
2
2009-10-28 18:59:46 +0000

In definitiva provare mv . fallirà perché mv non sarà in grado di scollegare la directory in cui vi trovate attualmente. Potreste mv * .. per spostare i file nella cwd.

2
2
2
2013-10-22 22:24:11 +0000

È più corretto usare lo schema * .[!.] .??* piuttosto che * .[^.] .??* poiché il primo funzionerà anche con shell più vecchie come ksh88:

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

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

2
2
2
2009-10-28 19:47:28 +0000
mv * .??* ../.

* ottiene tutti i file non-punto. .??* ottiene tutti i file . lunghi almeno tre byte, il che funziona per tutti quelli legittimi. Tutto ciò che rimane probabilmente vorrai comunque rm piuttosto che mv.

Lo ../. non offre alcun beneficio diretto rispetto allo .., ma quando si fa un move-to-directory è una buona abitudine da prendere, perché fallirà, come volete, se c'è qualcosa di sbagliato nel percorso. Per esempio, mv xyz bletch, dove si pensa che bletch sia una directory, può essere reso più sicuro con mv xyz bletch/..

0
0
0
2014-05-12 23:08:11 +0000

Anche Find e grep funzionano. Questo tipo di struttura potrebbe essere utile se si volesse selezionare i file in base a criteri più complicati modificando find e egrep.

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

mv `find -maxdepth 1 | egrep '^./.'` .. # mv <all files> ..
0
0
0
2014-08-06 16:37:16 +0000

Penso che la soluzione più semplice per spostare tutti i file nella sua cartella madre sarebbe

mv "`ls`" ../

oppure, se ci sono file/directory nascosti

use:

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

Inoltre, diciamo che si vuole spostare il contenuto di qualche cartella in una delle sue cartelle interne tony(diciamo)

usare:

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

Nota:

"`ls -a`"

per spostare i file che hanno degli spazi.

2>/dev/null

è per sopprimere l'avviso/errore perché ls -a stamperebbe anche le cartelle . e .. e non si possono spostare o copiare. Quindi per quelle cartelle mostrerà l'errore (se non usiamo 2>/dev/null) che non può spostarle e il resto sarà spostato abbastanza comodamente.

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