Come copiare file nascosti (a partire da un punto) e sottodirectory in Linux?


10

Come copiare file nascosti e sottodirectory nascoste (quelle che iniziano con un punto) nella cartella A nella cartella B? Ad esempio se ho questa struttura:

A/a
A/b
A/.a
A/.b/
A/.b/somefile
A/.b/.c

Vorrei copiare su B solo i file nascosti e le sottodirectory nascoste in A:

B/.a
B/.b/
B/.b/somefile
B/.b/.c

Ho già provato questo comando: cp A/.* Bda questa altra domanda da superutente . Tuttavia, non copia le sottodirectory. Anche provato cp -r A/.* B, ma copia .quindi finisco con una copia esatta di A (compresi i file normali). Qualsiasi aiuto è apprezzato.

Risposte:


16

Finché stai cercando solo file e cartelle nascosti a livello di A e non vuoi, per esempio

A/b/.hidden

per essere copiato, dovresti essere in grado di usare questo:

cp -r A/.[^.]* B

Fondamentalmente significa copiare tutto ciò che inizia con un .e quindi qualsiasi carattere diverso da un .filtro che filtra .e..

Modifica: rimosso -p dal comando cp poiché Asker non ha indicato di voler conservare proprietà, date, ecc.


Funziona con i nomi di file e directory di esempio forniti nella domanda, ma il testo della domanda dice "file nascosti e sottodirectory nascoste (quelle che iniziano con un punto)" e questa risposta non troverà file e directory i cui nomi iniziano con due punti; ad es ..c.
Scott,

È un caso piuttosto marginale, ma comunque una preoccupazione legittima. Non l'avevo considerato. Potresti spiegarlo passando a .*[^.]ma poi perderesti i file che terminano con a .. Penso che avresti davvero bisogno di estensioni per spiegare veramente tutti i casi.
Onnipresenza,

4

Il problema A/.*è che esiste la directory .in Acui corrisponde anche il modello.

È possibile attivare modelli glob estesi e utilizzare quanto segue:

shopt -s extglob
cp -r A/.!(?(.)) B    

Corrisponde ai file il cui nome inizia con un punto e il cui secondo carattere non è né un punto né niente (? (.) Corrisponde a niente o un punto,! (...) lo nega, ovvero! (? (.)) Corrisponde a tutto il resto di niente o un punto).


+1 per una risposta corretta. Si noti che .!(@(|.))(AFAICT) equivale a quanto sopra, (IMNSHO) un po 'più chiaro e solo un carattere in più.
Scott,

3

Per casi come questo consigliamo di utilizzare findinvece di cpquesto:

find A/ -type f -maxdepth 1 -name '.*' -exec cp -p {} B/ \;

La sintassi di base si suddivide in questo modo:

  • find A/ -type f: findelementi nella directory il A/cui tipo è un file (anziché una directory) ...
  • -maxdepth 1 -name '.*': A questo per una maxdepthdelle directory 1 e la cui nameinizia con ..
  • -exec cp -p {} B/ \;: E una volta trovati questi file, execil cpcomando con un -pflag per conservare le date / ore dalla sorgente ( {}) alla destinazione di B/.

Mi piace usare maxdepthper aggiungere un livello di controllo, quindi non sto copiando accidentalmente un intero file system. Ma sentiti libero di rimuoverlo.


0
 for item in `find A -type d | grep -E "\."` ; do cp -r $item B ; done
  • find A -type d fornisce un elenco ricorsivo all'interno di A con solo directory
  • grep -E "\." filtra le directory con un punto (es .: directory nascoste)
  • l'opzione -E era necessaria qui perché senza di essa significa anche "directory corrente"
  • la barra rovesciata è di evitare il significato, sotto regexp, di "qualsiasi carattere"
  • cp -r per copiare in modo ricorsivo

Ho creato la struttura di file e cartelle per A ed eseguito il comando in Git Bash (non sto con un Linux proprio ora) e ha funzionato.


Ciò si interrompe se i file hanno spazi bianchi o caratteri speciali nel loro nome o percorso.
slhck,

Grazie per averlo notato :) In realtà ho limitato il "caso di prova" di @gaboroncancio. Se puoi darmi un'altra batteria di prova, potrei provare a migliorarla (ovviamente se vuoi, migliorala da solo modificando questa risposta o creando una nuova risposta)
malarres

Potresti semplicemente mettere i dotfile in una cartella chiamata A B, e poi si comporterebbe inaspettatamente perché si espanderebbe cp -r A B/.dotfile B. Il consiglio generale è di non analizzare findo lsprodurre affatto. Se lo usi find, dovresti anche usare le sue opzioni per filtrare piuttosto che grep, e se esegui il pipe findoutput da qualche altra parte, usa -print0o chiama direttamente il comando che desideri. Vedere il find manuale di .
slhck,

Ancora più in generale, quando si lavora con i file è più sicuro usare i globi di shell come spiegato in altre risposte (anche se spesso richiedono extglobdi essere impostati).
slhck,

Grazie per il link Lasciamo findquindi l' analisi.
Malarres,

0

In alternativa puoi usare questo altro comando se il secondo carattere è alfanumerico ( sorgente ):

cp -r A/.[a-zA-Z0-9]* B

Funziona con i nomi di file e directory di esempio forniti nella domanda, ma il testo della domanda dice "file nascosti e sottodirectory nascoste (quelli che iniziano con un punto)" e questa risposta non troverà file e directory i cui nomi iniziano con un punto e un carattere speciale; ad es . .@foooppure ..c.
Scott,

Ecco perché indico che funziona se il secondo carattere è alfanumerico. ;)
gaboroncancio,
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.