Sposta tutti i file che non sono una directory


14

Ho una directory che sto cercando di ripulire che contiene sia file che sottodirectory. Quello che sto cercando di fare è semplice: spostare tutti i file in un'altra directory, ma lasciare tutte le sottodirectory come sono.

Sto pensando a qualcosa del tipo:

mv [*_but_no_dirs] ./other_directory

Sembra che ci dovrebbe essere un modo semplice per farlo con caratteri jolly *e regex ...

Qualcuno ha idee?


1
Quindi spostare tutti i file in una sottocartella, ma ignorarne qualcuno nelle sottodirectory?
Wilf,

@Wilf: esattamente.
Questionmark

2
In zsh, potresti farlo mv **/*(.) ./other_directory- con bash avresti comunque bisogno di ricorrere a comandi esterni come find.
godlygeek,

Risposte:


12

Regex non è coinvolto qui. I caratteri jolly in bash (come la maggior parte delle altre shell) corrispondono solo ai file in base ai nomi dei file, non in base al tipo di file o ad altre caratteristiche. Esiste un modo per abbinare per tipo: l'aggiunta /alla fine del modello fa corrispondere solo le directory o i collegamenti simbolici alle directory. In questo modo, puoi spostare le directory, quindi spostare ciò che rimane e spostare le directory indietro - ingombranti ma funziona.

tmp=$(TMPDIR=.. mktemp -d)
mv -- */ "$tmp"
mv -- * "$tmp"/other_directory/
mv "$tmp"/* .
rmdir "$tmp"

Un modo standard per abbinare i file per tipo è chiamare find.

find . -name . -o -type d -prune -o -exec sh -c 'mv "$@" "$0"' other_directory/ {} +

In zsh, puoi utilizzare i qualificatori glob per abbinare i file per tipo. Il .qualificatore corrisponde ai file regolari; utilizzare ^/per abbinare tutte le non directory o -^/per includere anche collegamenti simbolici alle directory.

mv -- *(.) other_directory/

In qualsiasi shell, puoi semplicemente eseguire il loop.

for x in *; do
   if ! [ -d "$x" ]; then
     mv -- "$x" other_directory/
   fi
done

8

Potresti usare qualcosa del genere

find . -maxdepth 1 \( ! -type d \) -exec sh -c 'mv  "$@" MYDIR' _ {} \;

Per prima cosa findguardiamo solo all'interno della directory corrente, quindi ignoriamo le directory usando ! -type d infine eseguiamo she spostiamo tutto nella directory di destinazione. Potresti provare {} +alla fine che sarà più veloce.


2
Un po 'di spiegazione, per favore ...
Questionmark

1
@Questionmark Ho aggiornato la risposta e ho aggiunto alcune spiegazioni. Inoltre, vale la pena visitare mywiki.wooledge.org/UsingFind
Valentin Bajrami,

Perché suggerisci -exec sh -c 'mv "$@" MYDIR' _ {} \;piuttosto che -exec mv {} MYDIR \;? Solo per ottenere qualcosa che può essere semplificato cambiando \;in a +? Puoi farlo con il -exec mv -t MYDIR {} +modulo.
Scott,

@Scott Non avevo idea della -tbandiera. Ho anche spiegato nella risposta che +è più veloce ma non tutte le findversioni lo supportano. Quindi il codice sopra è praticamente compatibile con qualsiasi findo shell utilizzata.
Valentin Bajrami,

1
@ val0x00ff: "... il codice sopra è praticamente compatibile con qualsiasi findo shell utilizzata." Vero, ma così è find … -exec mv {} MYDIR \;, e che utilizza meno risorse di … -exec sh -c 'mv "$@" MYDIR' _ {} \;.
Scott,

0

È potenzialmente un po 'pericoloso ma

cp * destination/
rm *

Poiché sia ​​cp che rm non funzioneranno su directory senza l'opzione -r.


-1

Suggerirei semplicemente di fare mv *.* destination/con destinazione / essendo la cartella in cui ci si sposta.



2
I nomi delle directory possono contenere 'punto' e i nomi dei file possono escluderlo (e spesso lo fanno), quindi *.*sposteranno alcune directory e lasceranno alcuni file, il che non è quello che voleva il richiedente.
dave_thompson_085,

Scusa ma questo è completamente sbagliato. Sposta semplicemente qualsiasi cosa con un punto nel suo nome e non sposta nulla senza uno. I punti non sono in alcun modo esclusivi dei file e non sono nemmeno richiesti dai file, quindi questo sposterà semplicemente una selezione casuale di file e directory.
terdon

-2
mv $(ls -l | grep "^-" | awk '{print $9}') ./folder_where_move
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.