it-swarm.it

Come si spostano tutti i file (inclusi quelli nascosti) da una directory a un'altra?

Come posso spostare tutti i file in una directory (compresi quelli nascosti) in un'altra directory?

Ad esempio, se ho una cartella "Foo" con i file ".hidden" e "notHidden" all'interno, come posso spostare entrambi i file in una directory denominata "Bar"? Quanto segue non funziona, poiché il file ".hidden" rimane in "Foo".

mv Foo/* Bar/

Prova tu stesso.

mkdir Foo
mkdir Bar
touch Foo/.hidden
touch Foo/notHidden
mv Foo/* Bar/
155
Cory Klein

Zsh

mv Foo/*(DN) Bar/

o

setopt -s glob_dots
mv Foo/*(N) Bar/

(Esci da (N) Se sai che la directory non è vuota.)

Bash

shopt -s dotglob nullglob
mv Foo/* Bar/

Ksh93

Se sai che la directory non è vuota:

FIGNORE='.?(.)'
mv Foo/* Bar/

Standard (POSIX) sh

for x in Foo/* Foo/.[!.]* Foo/..?*; do
  if [ -e "$x" ]; then mv -- "$x" Bar/; fi
done

Se sei disposto a lasciare che il comando mv restituisca uno stato di errore anche se ha avuto successo, è molto più semplice:

mv Foo/* Foo/.[!.]* Foo/..?* Bar/

GNU find e GNU mv

find Foo/ -mindepth 1 -maxdepth 1 -exec mv -t Bar/ -- {} +

Trova standard

Se non ti dispiace cambiare nella directory di origine:

cd Foo/ &&
find . -name . -o -exec sh -c 'mv -- "[email protected]" "$0"' ../Bar/ {} + -type d -Prune

Ecco ulteriori dettagli sul controllo della corrispondenza dei file dot in bash, ksh93 e zsh.

Bash

Imposta dotglob opzione .

$ echo *
none zero
$ shopt -s dotglob
$ echo *
..two .one none zero

C'è anche il più flessibile GLOBIGNORE variabile , che è possibile impostare su un elenco separato da due punti di motivi jolly da ignorare. Se non impostato (impostazione predefinita), Shell si comporta come se il valore fosse vuoto se dotglob è impostato e come se il valore fosse .* Se l'opzione non è impostata. Vedere Espansione nome file nel manuale. Le directory pervasive . E .. Sono sempre omesse, a meno che . Non sia abbinato esplicitamente al modello.

$ GLOBIGNORE='n*'
$ echo *
..two .one zero
$ echo .*
..two .one
$ unset GLOBIGNORE
$ echo .*
. .. ..two .one
$ GLOBIGNORE=.:..
$ echo .*
..two .one

Ksh93

Impostare la FIGNORE variabile . Se non impostato (impostazione predefinita), Shell si comporta come se il valore fosse .*. Per ignorare . E .., Devono essere abbinati esplicitamente (il manuale in ksh 93s + 2008-01-31 afferma che . E .. Sono sempre ignorati , ma questo non descrive correttamente il comportamento reale).

$ echo *
none zero
$ FIGNORE='@(.|..)'
$ echo *
..two .one none zero
$ FIGNORE='n*'
$ echo *
. .. ..two .one zero

È possibile includere file di punti in un modello abbinandoli esplicitamente.

$ unset FIGNORE
$ echo @(*|.[^.]*|..?*)
..two .one none zero

Per fare in modo che l'espansione risulti vuota se la directory è vuota, utilizzare l'opzione di corrispondenza dei pattern N: ~(N)@(*|.[^.]*|..?*) o ~(N:*|.[^.]*|..?*).

Zsh

Imposta l'opzione dot_glob .

% echo *
none zero
% setopt dot_glob
% echo *
..two .one none zero

. E .. Non vengono mai abbinati, anche se il modello corrisponde esplicitamente al . Iniziale.

% echo .*
..two .one

È possibile includere file di punti in un modello specifico con Dqualificatore glob .

% echo *(D)
..two .one none zero

Aggiungi il qualificatore N glob per rendere l'espansione vuota in una directory vuota: *(DN).


Nota: è possibile ottenere risultati di espansione del nome file in diversi ordini (ad esempio, none seguito da .one Seguito da ..two) In base alle impostazioni di LC_COLLATE, LC_ALL E LANG variabili.

#!/bin/bash

shopt -s dotglob
mv Foo/* Bar/

A partire dal man bash

dotglob Se impostato, bash include i nomi di file che iniziano con un '.' nei risultati dell'espansione del nome percorso.

24
SiegeX

Un modo semplice per farlo in bash è

mv {Foo/*,Foo/.*} Bar/

Ma questo sposterà anche le directory.

Se si desidera spostare tutti i file inclusi quelli nascosti ma non si desidera spostare alcuna directory, è possibile utilizzare un ciclo for e test.

for i in $(ls -d {Foo/*,Foo/.*});do test -f $i && mv -v $i Bar/; done;

11
Boris Month

Un modo è usare find:

find Foo/ -type f -exec mv -t Bar/ {} \+

Il -type f limita il comando find alla ricerca di file. Dovresti esaminare -type, -maxdepth, e -mindepth opzioni di find per personalizzare il tuo comando per tenere conto delle sottodirectory. Trova ha un lungo ma molto utile pagina del manuale .

4
Steven D

Prova il comando di copia cp:

$ cp -r myfolder/* destinationfolder

cp -r significa copia ricorsiva, quindi verranno copiate tutte le cartelle e i file.

È possibile utilizzare il comando remove rm per rimuovere una cartella:

$ rm -r myfolder

Vedi di più: sposta tutti i file da una directory a un'altra .

2
ucefkh

Per minimo distribuzioni Linux, dovrebbe funzionare come segue. Innanzitutto, esegui una mossa di base tutto (che manca i file nascosti). Quindi, sposta tutti i file nascosti (incluso . e .. che sarà non effettivamente spostato).

mv /sourceDir/* /destinationDir 2> /dev/null
mv /sourceDir/.* /destinationDir 2> /dev/null

Note: Se non c'è contenuto visibile, il primo comando produrrà un messaggio di errore. Il secondo comando sempre produrrà un errore dicendo che non può muoversi . e ... Pertanto, inserisci gli errori in /dev/null (come mostrato).

Se hai bisogno di questo come un liner, basta combinarli con un punto e virgola:

mv /sourceDir/* /destinationDir 2> /dev/null; mv /sourceDir/.* /destinationDir 2> /dev/null
1
BuvinJ

Rsync è un'altra opzione:

rsync -axvP --remove-source-files sourcedirectory/ targetdirectory

Questo funziona perché in rsync la barra finale conta, sourcedirectory/ si riferisce al contenuto della directory, mentre sourcedirectory si riferisce alla directory stessa.

Lo svantaggio di questo metodo è che rsync pulirà i file solo dopo lo spostamento, non la directory. Quindi ti rimane un albero di directory di provenienza vuoto. Per soluzioni alternative, vedere:

Spostare i file ed eliminare le directory con rsync?

Pertanto, sebbene ciò non sia ottimale per le operazioni di spostamento, può essere estremamente utile per le operazioni di copia.

1
Grumbel

Risposta per bash/pesce

Ecco un modo per farlo usando i caratteri jolly:

.[!.]* ..?* corrisponderà tutti i file nascosti tranne . e ..

.[!.]* ..?* * corrisponderà tutti i file (nascosti o meno) tranne . e ..

E per rispondere al particolare esempio di questa domanda è necessario cd foo && mv .[!.]* ..?* * ../bar

Spiegazione

.[!.]* corrisponde ai nomi dei file che iniziano con un punto, seguito da qualsiasi carattere tranne il punto facoltativamente seguito da qualsiasi stringa. Questo è abbastanza vicino ma manca i file che iniziano con due punti come ..foo. Per includere tali file aggiungiamo ..?* che corrisponde a nomi di file che iniziano con due punti, seguiti da qualsiasi carattere, facoltativamente seguito da qualsiasi stringa.

Test

È possibile testare questi caratteri jolly con i comandi seguenti. Li ho provati con successo sotto bash e pesce. Falliscono sotto sh, zsh, xonsh.

mkdir temp
cd temp
touch  a  .b  .bc  ..c  ..cd  ...d  ...de
ls .[!.]* ..?*
# you get this output:
          .b  .bc  ..c  ..cd  ...d  ...de
# cleanup
cd ..
rm -rf temp
1
ndemou

Trovo che questo funzioni bene per bash e non c'è bisogno di cambiare le opzioni di Shell

mv sourcedir/{*,.[^.]*} destdir/

MODIFICARE:

Quindi, come ha affermato G-man, la mia risposta originale non è conforme a posix ed è praticamente la stessa della risposta di ndemou sopra con una modifica, che è quella di utilizzare l'espansione del rinforzo per creare elenchi di stringhe su cui vengono quindi applicate. Questo significa solo che non è necessario cd nella directory di origine. Non è un grande cambiamento, ma è diverso.

esempio: supponiamo che tu abbia già il seguente layout.

 $ tree -a
.
├── destdir
└── sourcedir
    ├── ..d1
    ├── ..d2
    ├── ..double
    ├── file-1
    ├── file-2
    ├── .hidden-1
    ├── .hidden-2
    ├── ...t1
    └── ...t2

La domanda originale menzionava solo i file nascosti con un solo punto, ma supponiamo che ci siano alcuni con due o più punti all'inizio del nome. Puoi semplicemente aggiungere un'espressione aggiuntiva tra parentesi graffe. Possiamo quindi eseguire

mv sourcedir/{*,.[!.]*,..?*} destdir/

Questo viene espanso come segue:

mv sourcedir/file-1 sourcedir/file-2 sourcedir/.hidden-1 sourcedir/.hidden-2 sourcedir/..d1 sourcedir/..d2 sourcedir/..double sourcedir/...t1 sourcedir/...t2 destdir/

Ora dovresti vedere tutti i file che si trovano in destdir :

 $ tree -a
.
├── destdir
│   ├── ..d1
│   ├── ..d2
│   ├── ..double
│   ├── file-1
│   ├── file-2
│   ├── .hidden-1
│   ├── .hidden-2
│   ├── ...t1
│   └── ...t2
└── sourcedir

Puoi fare cose piuttosto interessanti con parentesi graffe in bash con ancora più aggiunte in 4.x. Dai un'occhiata a bash-hackers per alcuni eleganti esempi.

0
cmndr sp0ck

Potresti anche essere in grado di trovare e grep con backquotes per selezionare i file per il comando move. Passa quelli in mv.

Cioè Per file nascosti

find Foo -maxdepth 1 | egrep '^Foo/[.]' # Output: .hidden

Così

mv `find Foo -maxdepth 1 | egrep '^Foo/[.]'` Bar # mv Foo/.hidden Bar

Sposta solo i file nascosti selezionati in Bar:

mv `find Foo -maxdepth 1 | egrep '^Foo/.'` Bar # mv Foo/.hidden Foo/notHidden Bar

Sposta tutti i file in Foo su Bar dal '.' nel comando egrep funge da carattere jolly senza parentesi quadre.

Il ^ carattere assicura che la partita inizi dall'inizio della riga.

Alcuni dettagli sulla corrispondenza del motivo egrep sono disponibili qui .

Utilizzando maxdepth 1 impedisce che la ricerca vada nelle sottodirectory.

0
user3192145

Ispirato da questa risposta :

Senza copiare i file ...

rsync -ax --link-dest=../Foo/ Foo/ Bar

Avvertenze:

  • --link-dest il percorso deve essere assoluto o relativo a DESTINATION (Bar nell'esempio)

  • Devi mettere / dopo SOURCE (Foo/ nell'esempio), altrimenti copierà la cartella SOURCE anziché il suo contenuto.

0
palindrom