Come faccio a copiare il file denominato che inizia con un punto?


26

Sto cercando di copiare tutti i file nella directory A nella directory B. Tutti i file nella directory A iniziano con il punto, ad esempio:

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

che ho trovato se uso cp A/* B:, ottengo sempre l'errore:

cp: cannot stat 'A/*': no such file or directory

Sembra che non ci sia alcuna opzione per cpcome lsgestire le voci iniziate con il punto, qualcuno ha idea di come risolverlo?

Risposte:


34

Il motivo è perché in bash, *non include i file che iniziano con dot ( .).

Puoi correre

cp A/.* B

Ti avvertirà che non ha copiato .o .., o nessuna sottodirectory, ma questo va bene.

Oppure, se si desidera copiare insieme file dot e file normali, eseguire

cp A/.* A/* B

Potresti anche correre

shopt -s dotglob
cp A/* B

che funzionerà bash, ma non sh.

E se non ti dispiace che anche le sottodirectory vengano copiate, questa è la più semplice:

cp -R A/ B

Suggerimento: se mai i caratteri jolly non fanno ciò che ti aspetti, prova a eseguirlo con l'eco, ad es

$ echo A/*
A/file1 A/file2

$ echo A/.*
A/. A/.. A/.hidden1 A/.hidden2

$ echo A/.* A/*
A/. A/.. A/.hidden1 A/.hidden2 A/file1 A/file2

$ shopt -s dotglob
$ echo A/*
A/file1 A/file2 A/.hidden1 A/.hidden2

Questo è solo un problema se lo usi -r. Senza -r, salterà semplicemente le directory.
Mikel,

E anche l'esempio che uso -Rdovrebbe funzionare bene. Se ritieni che sia sbagliato, spiega perché.
Mikel,

7

Se bash, è possibile impostare dotglobprima di copiare

shopt -s dotglob
cp A/* /destination

O un linguaggio di programmazione

$ ruby -rfileutils -e  'Dir[".*"].each {|x| FileUtils.copy(x,"/destination") if File.file?x}'

Se non vuoi impostare dotglob, basta

cp A/.* /destination 2>/dev/null

Usando dotglob OP copierai anche tutti i file non nascosti, che non è quello che vuole.
peoro

@peoro, dovresti leggere di nuovo la domanda. Tutti i file in Asono nascosti. Vuole solo copiarlo.

7

Quello che stai cercando è più sulla falsariga di:

cp A/.??* B/

Questo corrisponderà a tutti i dotfile, ma non a "." o "..". La maggior parte delle soluzioni di cui sopra va bene finché non si lavora in modo ricorsivo. Ma non appena vuoi fare qualcosa del genere:

cp -R A/.??* B/

Senza omettere ".." copierai tutto dalla directory principale in giù, inclusi i non-dotfile.


1
Questo mancherà dot-file che sono un singolo carattere, come .ao .x. Il modello di globbing più corto che ho trovato corrisponde a tutti i file dot tranne .ed ..è .[^.]*.
pavone,

2

Ho appena provato il seguente e funziona solo trovare ...

cp A/.* B/

2
Anche questo passerà A/.e A/..come parametri a cp, che potrebbe essere problematico nel caso in cui OP debba anche copiare le directory (usando cp -r)
peoro

2

Non cpè colpa , è bash: bash si espande *in tutti i file non nascosti (ovvero: non a partire da .).

Bash si espanderà .*(quindi A/.*, nel tuo caso) con tutti i file che iniziano con ., ma sfortunatamente include anche .e ..(directory correnti e parent) che probabilmente vorrai saltare. (Nota che altre shell, come zsh, non le includerebbero, e anche IIRC bash, dopo aver impostato alcune opzioni).

Una soluzione semplice potrebbe essere quella di rimuovere .e ..dai file corrispondenti .*, in un modo (molto) confuso come questo:

cp $( for F in A/.*; do echo $F | grep -v "^\.*$"; done ) B

o questo (probabilmente più pulito: utilizza findper trovare i file da copiare):

cp $( find A -maxdepth 1 -mindepth 1 -name ".*" ) B

ma probabilmente troverai soluzioni più pulite.


perché dovresti usare un for loope quindi creare un grepprocesso extra solo per fare un lavoro come cp A/.*? cpignorerà il "." e ".." directory.

1

Se iniziano tutti con un punto, basta usare A/.*:

[holt@Michaela test]$ cp A/* B
cp: cannot stat `A/*': No such file or directory

[holt@Michaela test]$ cp A/.* B
cp: omitting directory `A/.'
cp: omitting directory `A/..'
[holt@Michaela test]$ ls -al B
total 8
drwxrwxr-x. 2 holt holt 4096 2011-03-31 16:57 .
drwxrwxr-x. 4 holt holt 4096 2011-03-31 16:57 ..
-rw-rw-r--. 1 holt holt    0 2011-03-31 16:57 .a
-rw-rw-r--. 1 holt holt    0 2011-03-31 16:57 .b
-rw-rw-r--. 1 holt holt    0 2011-03-31 16:57 .c

Spero che sia di aiuto!


1

Puoi usare questo script

IFS = $ '\ n'; per act in $ (trova A -d 1); do cp -R "$ act" B; fatto


0

copia:

cp A/.* B

elenco:

ls -l A/.*

elenca i file senza directory discendenti:

ls -ld A/.*

0

Devi escludere e .. dall'elenco dei file passato a cp!

Questo è sicuro:

ls -1d A/.[a-zA-Z]* | xargs -i cp -rp {} B

0

Questo è un vecchio thread ... ma sono sempre stato in grado di copiare tutti i file. Compresi file / cartelle che iniziano con '.'

Esempio copierà tutti i file e le cartelle:

cp -aup /root/.* / backup / root /

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.