¿Cómo copio el archivo llamado que comienza con un punto?

26

Estoy tratando de copiar todos los archivos en el directorio A al directorio B. Todos los archivos en el directorio A comienzan con punto, por ejemplo:

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

que encontré si uso: cp A/* Bsiempre obtengo error:

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

Parece que no hay opción de cpque lspara manejar las entradas iniciadas con el punto, alguien tiene idea de cómo solucionarlo?

usuario59285
fuente

Respuestas:

34

La razón es porque en bash, *no incluye archivos que comienzan con dot ( .).

Tu puedes correr

cp A/.* B

Se le advertirá que no copió .o .., o cualquier subdirectorio, pero esto está muy bien.

O, si desea copiar archivos de puntos y archivos normales juntos, ejecute

cp A/.* A/* B

También podrías correr

shopt -s dotglob
cp A/* B

que funcionará bash, pero no sh.

Y si no le importa que también se copien subdirectorios, entonces esta es la más fácil:

cp -R A/ B

Consejo: Si alguna vez los comodines no están haciendo lo que espera, intente ejecutarlo con echo, p. Ej.

$ 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
Mikel
fuente
Eso es solo un problema si lo usas -r. Sin -r, simplemente se saltará los directorios.
Mikel
Y el ejemplo que doy usando también -Rdebería funcionar bien. Si cree que está mal, explique por qué.
Mikel
7

Si bash, puede configurar dotglobantes de copiar

shopt -s dotglob
cp A/* /destination

O un lenguaje de programación

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

Si no quieres configurar dotglob, solo

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

fuente
El uso de dotglob OP también copiará todos los archivos no ocultos, que no es lo que quiere.
peoro 01 de
@peoro, deberías leer la pregunta nuevamente. Todos los archivos Aestán ocultos. Él solo quiere copiar eso.
7

Lo que estás buscando es más parecido a:

cp A/.??* B/

Esto coincidirá con todos los archivos de puntos, pero no con "." o "..". La mayoría de las soluciones anteriores están bien siempre que no trabaje de forma recursiva. Pero tan pronto como quieras hacer algo como:

cp -R A/.??* B/

Sin omitir "..", copiará todo desde el directorio principal hacia abajo, incluidos los archivos sin puntos.

John Westlund
fuente
1
Esto perderá los archivos de puntos que son un solo carácter, como .ao .x. El patrón de globbing más corto que he encontrado que coincide con todos los archivos de puntos, excepto .y ..es .[^.]*.
Pavón
2

Acabo de intentar lo siguiente y funciona solo encontrar ...

cp A/.* B/
Andrew White
fuente
2
Esto también pasará A/.y A/..como parámetros a cp, lo que podría ser problemático en el caso de OP también tiene que copiar los directorios (usando cp -r)
peoro
2

Eso no cpes culpa , es bash: bash se expande *en todos los .archivos no ocultos (es decir, no comienzan con ).

Bash se expandirá .*(por lo tanto A/.*, en su caso) con todos los archivos que comienzan ., pero desafortunadamente también incluye .y ..(directorios actuales y principales) que probablemente querrá omitir. (Tenga en cuenta que otros shells, como zsh, no los incluirían, y IIRC también golpean, después de configurar algunas opciones).

Una solución fácil podría ser eliminar .y ..de archivos que coincidan .*, de una manera (muy) hacky como esta:

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

o este (probablemente más limpio: se usa findpara encontrar los archivos para copiar):

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

pero probablemente encontrarás soluciones más limpias.

peoro
fuente
¿por qué deberías usar ay for loopluego crear un grepproceso adicional solo para hacer un trabajo como cp A/.*? cpignorará el "." y directorios "..".
1

Si todos comienzan con un punto, simplemente use 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 esto ayude!

Xavier Holt
fuente
1

Puedes usar este script

IFS = $ '\ n'; para actuar en $ (encontrar A -d 1); hacer cp -R "$ act" B; hecho

teki
fuente
0

dupdo:

cp A/.* B

lista:

ls -l A/.*

Listar archivos sin directorios descendentes:

ls -ld A/.*
Beato Geek
fuente
0

Debe excluir y .. de la lista de archivos pasados ​​a cp!

Esto es seguro:

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

Este es un hilo viejo ... pero siempre he podido copiar todos los archivos. Incluyendo archivos / carpetas que comienzan con '.'

Ejemplo copiará todos los archivos y carpetas:

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

Ontologik
fuente