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.