Frammenta lo snippet per spostare tutti i file in una directory in quella directory


14

Ho una directory con molti file e directory. Per riordinare, ho intenzione di mettere tutti quei file in una directory, quindi stavo per fare qualcosa del genere:

$ ls | wc -l
123
$ mkdir new_directory
$ mv * ./new_directory

Tuttavia che, ovviamente, non funzionerà perché poi proverà a muoversi new_directoryin new_directory. C'è un modo semplice per fare ciò che voglio in una riga senza che io debba copiare e incollare tutti i file e le directory in quella directory?


3
funziona, stampa solo un messaggio di errore che non è in grado di spostare new_directory in se stesso.
CAS

Risposte:


18

Il tuo

mv * ./new_directory
il comando funzionerà effettivamente; stamperà solo un avviso che non può spostare quella directory in se stessa.


L'unico problema con questo è che se l'espansione totale del comando diventa troppo lunga (ovvero troppi file, nomi troppo lunghi) non funzionerà più.
Niels Basjes,

Come nota a margine, se hai intenzione di farlo con un git mvdevi usare il -kflag, poiché git fallirà per impostazione predefinita, non solo emetterà un avviso. Quindi dovrai farlo git mv -k * ./new_dir.
Yuval A

11

Un oneliner veloce e sporco.

mv `ls -A | grep -v new_directory` ./new_directory

1
Non funzionerà: semplicemente non mostrerà dotfile.
wzzrd,

Ottimo punto Risolto il problema con un -a.

2
Quindi invece di provare a spostare new_directory su se stesso (domanda originale) ora stai provando a muoverti. e .. in new_directory.
Niels Basjes,

2
Grazie per il feedback Niels. Risolto il problema con una a superiore che rimuove il file. e il .. dall'elenco della directory.

8

Se stai solo cercando i file (cioè non le directory), allora

find . -type f -maxdepth 1 -exec mv {} ./new_directory/ \;

è la soluzione più portatile. Per velocità, dovresti spostare find e xargs, con -print0 e -0, ma solo se hai GNU find e xargs.


3
Usando una ricerca GNU abbastanza recente, puoi anche usare \ + invece di \; per ridurre il numero di mv che stiamo realizzando.
wzzrd,

Se hai GNU find, dovresti anche usare xargs, che farà lo stesso e ti permetterà di eseguire più mv contemporaneamente con il flag -p.
Cian,

bello uso di find- anche se sono stato sicuramente su sistemi che non ne hanno uno, purtroppo :(
warren

Veramente? find è (afaik) specificato in SUS, quindi tutto dovrebbe averlo. L'unico problema è se GNU find (che ha molte belle opzioni interessanti) o find regolari.
Cian,


6

Le volte che ho avuto questo problema, ho fatto una delle seguenti operazioni:

$ mkdir ../new-directory
$ mv * ../new-directory/
$ mv ../new-directory .

o

$ mkdir .new-directory
$ mv * .new-directory/
$ mv .new-directory new-directory

Il secondo modulo sfrutta i caratteri jolly che saltano i nomi dei file che iniziano con "."


Ho dimenticato i file punteggiati saltati con caratteri jolly; grazie per il promemoria ! :)
aemonge,

2

che dire:

cd ..
mv old_dir new_directory
mkdir old_dir
mv new_directory old_dir

IOW, non spostare il contenuto in una nuova directory, ma inserirla in una nuova directory.


1

In modo simile alla risposta di @Rebrane (anche se non un singolo):

for FN in *
do
    if [ "<new_dir>" != $FN ] then
        mv $FN <new_dir>
done

Questo dovrebbe essere portatile al 100%, anche se findè tristemente assente dal tuo sistema.


find è richiesto nella specifica unix singola. In quanto tale, non dovrebbe mai essere assente (non che non si potesse costruire qualcosa senza di esso. Ma immagino che richiederebbe una quantità orribile di sforzo, e nessun sistema di distributori lo mancherà)
Cian

forse è qualche sysadmin iper-paranoico che cerca i findutils o il suo equivalente? non sono sicuro, ma so di essermi imbattuto in boxen che non ce l'hanno :(
warren

1

I miei suggerimenti: Come affermato da altri il

mv * ./new_directory

funzionerà trovare IFF l'espansione totale è abbastanza breve.

Altro saggio puoi provare questo che si ridimensiona a un numero di file molto più grande:

find . -type f -maxdepth 1 | xargs -s100000 echo | xargs -iXXX mv XXX new_directory

Spiegazione

  1. Elenca tutti i file.
  2. Raggruppa tutti i nomi di file in blocchi di massimo 100000 caratteri.
  3. Costruisci un singolo comando mv per blocco.

si interrompe se si dispone di spazi nei nomi dei file
Cian

Hai ragione. Quindi suppongo che questo dovrebbe essere aumentato con -print0 e -0 flag per risolvere.
Niels Basjes,

Ho provato con -print0e -0ed ancora si rompe.
Cristian Ciupitu,

find: warning: hai specificato l'opzione -maxdepth dopo un argomento non -type -type, ma le opzioni non sono posizionali (-maxdepth influenza i test specificati prima e quelli specificati dopo). Si prega di specificare le opzioni prima di altri argomenti.
Cristian Ciupitu,

1

Uso:

find -mindepth 1 -maxdepth 1 \! -name new_directory -print0 | \
    xargs -0 -P 100 -I'{}' mv '{}' new_directory

Dalla xargspagina man:

-P max-procs

  Run up to max-procs processes at a time;

-1

Per evitare il messaggio di errore e mantenerlo semplice:

mv *.* ./new_Folder

farà la stessa cosa ma eviterà il messaggio di errore (a meno che tu non abbia dei punti nei nomi delle cartelle, immagino).

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.