Il comando che stai cercando è
mv * .[^.]* ..
o (vedi sotto per maggiori informazioni):
(shopt -s dotglob; mv -- * ..)
Spiegazione:il mv
comando sposta file e directory. L'ultimo argomento di mv
è l'obiettivo (in questo caso la directory un gradino "sopra" 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 (dotfiles) sono "nascosti". Vengono abbinati utilizzando il pattern .[^.]*
(vedi modifica sotto).
Vedi la manpage che ho collegato per maggiori informazioni su mv
.
Perché .[^.]*
invece di .*
?
Come sottolinea correttamente Chris Johnsen:il modello .*
corrisponde anche a .
e ..
. Dal momento che non vuoi (e non puoi) spostarli, è meglio usare uno schema che corrisponda a qualsiasi nome di file che inizi con un punto tranne quei due . Il modello .[^.]*
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 sottolinea Paggas, dovremmo anche aggiungere il pattern .??*
per far corrispondere 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 dotfile. 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
richiesto) e usa --
in modo che i file che iniziano con un trattino non vengano interpretati come argomenti di mv
.
Risposta breve:usa
find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +
Risposta lunga:
Il comando
mv * .* ..
non funzionerà dal .*
può corrispondere a .
e ..
. Ma il comando
mv * .[^.]* ..
inoltre non funzionerà, poiché .[^.]*
non corrisponderà, ad esempio, ..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 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 * .[^.] .??* ..
!
Giusto per completezza, si può anche dire alla shell Bash di includere i file nascosti, usando shopt
:
shopt -s dotglob
mv -- * ..
shopt -u dotglob