Como eu copio o arquivo nomeado começando com um ponto?

23

Eu estou tentando copiar todos os arquivos no diretório A para o diretório B. Todos os arquivos no diretório A estão começando com ponto, por exemplo:

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

que eu encontrei se eu usar: cp A/* B , sempre erro:

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

Parece que não há opção para cp como ls para manipular entradas iniciadas com ponto, alguém tem ideia de como corrigi-lo?

    
por user59285 01.04.2011 / 01:54

10 respostas

34

O motivo é porque, em bash , * não inclui arquivos que começam com ponto ( . ).

Você pode executar

cp A/.* B

Ele irá avisá-lo que não copiou . ou .. , ou quaisquer subdiretórios, mas está tudo bem.

Ou, se você quiser copiar arquivos de ponto e arquivos normais juntos, execute

cp A/.* A/* B

Você também pode executar

shopt -s dotglob
cp A/* B

que funcionará em bash , mas não em sh .

E se você não se importar com os subdiretórios sendo copiados, então é o mais fácil:

cp -R A/ B

Dica: se os curingas já não estiverem fazendo o que você espera, tente executá-los com eco, por exemplo,

$ 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
    
por 01.04.2011 / 01:58
7

Se bash, você pode definir dotglob antes de copiar

shopt -s dotglob
cp A/* /destination

Ou uma linguagem de programação

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

Se você não quiser definir o dotglob, apenas

cp A/.* /destination 2>/dev/null
    
por 01.04.2011 / 02:04
5

O que você está procurando é mais nos seguintes termos:

cp A/.??* B/

Isso irá corresponder a todos os dotfiles, mas não "." ou "..". A maioria das soluções acima são boas, desde que você não esteja trabalhando recursivamente. Mas assim que você quiser fazer algo como:

cp -R A/.??* B/

Sem omitir ".." você copiará tudo do diretório pai para baixo, incluindo os não-dotfiles.

    
por 05.05.2014 / 20:07
2

Acabei de tentar o seguinte e funciona só para encontrar ...

cp A/.* B/
    
por 01.04.2011 / 01:58
2

Isso não é culpa do cp , ele é o bash: o bash expande * em todos os arquivos não ocultos (ou seja: não começando com . ).

O Bash expandirá .* (portanto, A/.* , no seu caso) com todos os arquivos que começam com . , mas infelizmente inclui também . e .. (diretórios atuais e principais) que você provavelmente quer pular. (Note que outros shells, como zsh, não os incluiriam, e o IIRC também bash, depois de definir algumas opções).

Uma solução fácil poderia ser remover . e .. dos arquivos correspondidos por .* , de uma maneira (muito) hacky como esta:

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

ou este (provavelmente mais limpo: usa find para encontrar os arquivos para copiar):

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

mas você provavelmente encontrará soluções mais limpas.

    
por 01.04.2011 / 02:02
1

Se todos começarem com um ponto, use apenas 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

Espero que isso ajude!

    
por 01.04.2011 / 01:58
1

Você pode usar este script

IFS=$'\n';for act in $(find A -d 1); do cp -R "$act" B; done

    
por 13.07.2012 / 05:29
0

copiar:

cp A/.* B

lista:

ls -l A/.*

lista os arquivos sem os diretórios descendentes:

ls -ld A/.*
    
por 01.04.2011 / 02:00
0

Você deve excluir. e .. da lista de arquivos passada para o cp!

Isso é seguro:

ls -1d A/.[a-zA-Z]* | xargs -i cp -rp {} B
    
por 20.04.2014 / 18:00
0

Este é um tópico antigo ... mas sempre consegui copiar todos os arquivos. Incluindo arquivos / pastas que começam com '.'

Exemplo copiará todos os arquivos e pastas:

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

    
por 15.12.2017 / 08:21