Copia ricorsiva di file nascosti - Linux


19

C'è un modo semplice per copiare ricorsivamente tutti i file nascosti in una directory in un'altra directory? Vorrei eseguire il backup di tutti i file delle impostazioni in una directory home, non dei file normali. Provai:

cp -R .* directory

ma riconosce .e ..copia in modo ricorsivo anche tutti i file non nascosti. C'è un modo per far ignorare cp .e ..?


C'è qualche differenza tra -re -R?
Chaminda Bandara,

Risposte:


15

Il mio preferito per spostare dir in generale è stato:

tar cvf - . | (cd /dest/dir; tar xvf -)

che sintonizza la directory corrente su stdout, quindi la reindirizza a una subshell che dapprima cd alla directory di destinazione prima di annullare lo stdin. Semplice, diretto, estensibile: considera cosa succede quando sostituisci () con un ssh a un'altra macchina. O per rispondere alla tua domanda potresti fare:

tar cvf - .* --exclude=\. --exclude=\.\. | (cd /dest/dir; tar xvf -)

1
Grazie, l'opzione di esclusione è ciò di cui avevo bisogno. L'ho già fatto nell'altro modo, ma lo terrò per riferimento futuro. Questo sembra davvero flessibile (anche se forse più lento).
Zifre,

1
Buon Consiglio. Ho un paio di miglioramenti: 1) Usa cd /dest/dir && tar xvf -. Questo &&ti impedirà di cancellare sulla directory di origine se hai un refuso nella destinazione. 2) Hai solo bisogno della vbandiera tar su uno dei comandi tar (o nessuno dei due).
Tom Shaw,

Giusto. Sono stato anche conosciuto per raggruppare le cose nell'altro modo: per copiare uno srcdir remoto qui, fai(cd /src/dir && tar cf - .) | tar xvf -
pjz

17

Quasi ogni volta questo può essere risolto solo con:

cp -R .[a-zA-Z0-9]* directory

È abbastanza insolito avere un file nascosto che non inizia con uno di quei personaggi.

Sono disponibili altre corrispondenze di modelli ( .??*, .[^.]*): vedere i commenti


Ciò ignorerà solo.-Xyz - la roba in [] corrisponde solo al primo carattere dopo il punto.
Hamish Downer,

6
. [^.] * catturerebbe tutto
falstro,

1
... tranne le cose che iniziano con due punti.
falstro,

@roe - anche questa è una bella versione
Alnitak,

@mish - sì, ho detto altrettanto nella risposta.
Alnitak,

11

Puoi usare rsync.

rsync -a ./ /some/other/directory/

che copierà il contenuto della directory corrente (inclusi i file dot, ma non inclusi ..)


Semplice e funziona anche per file nascosti in cartelle nascoste.
user59183

per me questa è la soluzione meno confusa ed efficace delle soluzioni fornite
palerdot

Bella soluzione. Ne avevo anche bisogno per non copiare tra le .gitdirectory. L'aggiunta di -C fa questo e così il comando diventa:rsync -aC ./ /some/other/directory/
theruss

10

Vi imploro, passo di espansione shell pianura sulla cplinea di comando - di espansione shell ha tutti i tipi di ahem . "Interessanti" casi d'angolo (ricorsione indesiderati causati da e .., spazi, roba non stampabile, collegamenti fisici, link simbolici, e così via.) Usa findinvece (viene fornito nel findutilspacchetto, nel caso in cui non lo hai installato - il che sarebbe strano, tutte le distribuzioni lo installano per impostazione predefinita):

find -H /path/to/toplevel/dir/ -maxdepth 1 -name '.*' -a \( -type d -o -type f -o -type l \) -exec cp -a '{}' /path/to/destination/dir/ \;

Spiegazione dettagliata:

  • -Hfarà sì che findnon seguano i collegamenti simbolici (tranne se il nome della directory di livello superiore che hai fornito è un collegamento simbolico; che seguirà).
  • /path/to/toplevel/dir/ è ovviamente supposto che tu debba essere sostituito da te con il percorso della directory che ospita i file delle impostazioni e le directory di cui vuoi eseguire il backup.
  • -maxdepth 1smetterà finddi scendere ricorsivamente in tutte le directory il cui nome inizia con un punto. Non ne abbiamo bisogno per cpricorrere , lo faremo per noi, abbiamo solo bisogno dei nomi a questo livello.
  • -name '.*'dice findche vogliamo tutti i nomi che iniziano con un punto. Questo non funzionerà correttamente se la variabile di ambiente POSIXLY_CORRECTè impostata, ma raramente (se mai) lo è. Questa è la prima condizione di corrispondenza che abbiamo specificato finora.
  • a \( ....... \)è una e seguita da una condizione più complessa tra parentesi (l'ho usata ..... per sostituirla, è spiegata di seguito). Dobbiamo sfuggire alle parentesi poiché altrimenti sarebbero (erroneamente) interpretate dalla shell, da qui la barra rovesciata davanti a loro,
  • -type d -o -type f -o -type lsono tre condizioni con una o tra di loro. -type dcorrisponde alle directory, -type fai file regolari e ai -type llink simbolici. È possibile selezionare ciò che si desidera, ad esempio se non si desidera eseguire il backup delle directory delle impostazioni, omettere -type d(e il -odiritto dietro di esso, ovviamente.)
  • -exec ..... \;dice finddi eseguire un comando ogni volta che si incontra una corrispondenza. La fine del comando è contrassegnata da un punto e virgola, a cui dobbiamo nuovamente fuggire con una barra rovesciata per evitare l'interpretazione della shell. All'interno di quella riga di comando, devi utilizzare il punto in {}cui vuoi che finisca il nome della corrispondenza attualmente incontrata. Poiché le conchiglie potrebbero anche interpretare erroneamente le parentesi graffe, è necessario posizionarle in apostrofi, come in '{}'. Il comando che vogliamo eseguire in questo caso è cp -a '{}' /path/to/destination/dir/(-a significa archivio, che ricorre in sottodirectory, copia collegamenti simbolici come collegamenti e conserva permessi e attributi estesi, ed /path/to/destination/dir/è ovviamente il nome della directory di destinazione - sostituiscilo.)

Quindi, in parole povere, questa findriga di comando dice questo:

Inizia da / path / to / toplevel / dir /. Non scendere in nessuna sottodirectory. Trova tutte le directory, i file e i collegamenti simbolici il cui nome inizia con un punto. Per ognuno di quelli che hai trovato, copialo in / percorso / in / destinazione / dir / preservando natura, permessi e attributi estesi.


1
find è la cosa più utile di sempre.
Mr. Shiny e New 安 宇

1
Bella risposta. Anche se preferisco -exec ... ';' Evitare la barra rovesciata significa che questo comando funzionerà sia nella CLI che nella crontab :))
kubanczyk,

8

Ho sempre usato. ?? * per trovare file nascosti senza ottenere "." e "..". Potrebbe mancare ".a" o qualcosa del genere, però, ma non ne ho mai uno.


sicuramente carino e pulito :) +1
falstro

Non voglio che fallisca misteriosamente se ci sono alcuni ".a" s
Zifre

Mi piace perché se sai di non avere file nascosti a carattere singolo, è davvero veloce da scrivere.
Paul Tomblin,

Questa deve essere la risposta migliore. Dovrebbe essere votato verso l'alto.
Ibn Saeed,

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.