Copie el contenido del directorio utilizando el comando 'cp'

33

¿Cómo se copia todo el contenido de un directorio en otro?

Por ejemplo:

$ cd /home/newuser
$ cp -a /backup/olduser/* .

El problema con lo anterior es que el patrón global '*' coincide con los directorios ocultos '.' y '..' y terminas con un directorio 'olduser' dentro de 'newuser', así como los contenidos.

También podrías hacer algo como esto:

$ rmdir /home/newuser
$ cp -a /backup/olduser /home/newuser

Pero, ¿qué pasa si newuser ya contiene algunos archivos y directorios predeterminados?

¿Cuál es la forma más simple, más correcta, más fácil de recordar y no desordenada de mover el contenido de un directorio a otro usando solo el comando básico 'cp' y el shell?

Der Hochstapler
fuente

Respuestas:

31

Tratar:

cp -ra /backup/olduser/. /home/newuser
nagul
fuente
Esto es genial, pero no puedo entender exactamente cómo funciona. Creo que probablemente sea porque no entiendo cómo .y cómo ..trabajo. ¿Le importaria explicar?
bradley.ayers
Esto funcionó para mí pero cp -r ./a bno lo hizo. ¿Alguna idea de por qué?
Brig
3
A mí también me funciona, pero la ropción no es necesaria. La aopción implica r.
MountainX
1
¡El parámetro -r parece ser un poco redundante en este punto!
Maestro de Celebración
El -aparámetro no hace nada para ayudar en esta situación. El comando cp -r ./a/. bcopiará el contenido, y solo el contenido, del directorio aen el directorio b. La -abandera conserva enlaces, marcas de tiempo, etc., que no es relevante para la pregunta.
Steen Schütt
23

Dos directorios a y b.

Ambos tienen archivos.

Estás en un directorio que contiene ay b.

cp -r ./a b

-r = recursivamente.

Rich Bradshaw
fuente
¿No quieres que -a obtenga todos los archivos?
bw
77
El argumento -a no tiene nada que ver con todos los archivos, es corto para el archivo, preservará la propiedad del archivo, los permisos, los tiempos de acceso, etc. El argumento -a (aunque es muy útil) no es una opción estándar, y varias implementaciones de cp no No lo proporciones.
theotherrecibido el
1
@mch: incluido automáticamente, porque le ha dicho cpque copie un directorio ay a/.somedotfileestá contenido en a. si bexiste, este comando creará una copia exacta de aat b/a.
quack quijote
2
Manera fácil:cp -R /some/dir/* /another/dir
n0pe
1
Esto copia a / foo a b / a / foo en lugar de a b / foo
Sparr
19

Recuerde que, por defecto, cpcopia el primer directorio en el segundo directorio si existe el segundo.

Por ejemplo cp -r a b, copiará el directorio a en b. Si bno existe, se creará con el contenido de a.

Si desea copiar el contenido de aen b(por ejemplo, al copiar un sistema de archivos completo en un punto de montaje) use:

cp -r a/. b

como en la respuesta anterior

Tenga en cuenta también que -a, utilizado en algunas de las otras respuestas, es el mismo -dr --preserve=ally conservará las marcas de tiempo, el contexto y los atributos extendidos.

Nicolas Bonnefon
fuente
¿Cómo funciona el /.trabajo?
bradley.ayers
a/.representa el contenido del directorio 'a' en oposición al directorio en sí, en la mayoría de las situaciones es sinónimo, pero cuando se usa cp -r, evita el comportamiento predeterminado de cp (copiando un INTO b).
Nicolas Bonnefon
consejo increíble, esto es exactamente lo que estaba buscando pero no pude encontrar en otro lugar: todo ese 'foo / *' o '-r foo /' que falla en los casos de esquina.
Tener
@TimoHuovinen '.' no es un comodín en absoluto. Literalmente es el directorio "padre" y '..' es el abuelo. Esto significa '/foo/./././././.' es el mismo directorio que '/ foo', y '/ foo / bar / ..' es el mismo directorio que '/ foo'. Piense en ellos como enlaces duros incorporados al sistema de archivos.
quuxman
@quuxman gracias, no lo sabía en ese entonces. Voy a eliminar mi antiguo comentario para evitar confundir a las personas.
Timo Huovinen
6

A menos que haya reconfigurado seriamente su caparazón, el patrón de bloqueo '*' no coincide '.' o '...', como puede verificar con solo echo *. Lo que hace es omitir archivos cuyo nombre comienza con un '.', Por lo que su enfoque perderá todos los archivos ocultos. Puede ajustar parte de este comportamiento con las opciones de shell, por ejemplo, la opción dotglob en bash, pero no será la opción portátil y robusta que está buscando.

Si necesita hacer esto más de una o dos veces, le recomiendo que busque en rsync o al unísono (dependiendo de las necesidades específicas) con especificaciones de origen y destino cuidadosamente elaboradas.

Otra alternativa es colocar el directorio de origen en un tarball y descomprimirlo sobre el directorio de destino existente.

Peter Eisentraut
fuente
1
uso esto: ( cd /src/dir ; tar cf - . ) | ( cd /dest/dir ; tar xf - )... el tar cf - .tar es el directorio fuente, incluidos los archivos de puntos, y lo escupe a STDOUT, que se canaliza al STDIN del tar xf -.
quack quijote
Creo que el punto principal del OP es cómo hacer referencia a los archivos que comienzan con '.' pero no el especial '.' y '...' directorios. Hay una solución mucho más elegante arriba en lugar de usar rsync o algún otro programa complejo.
quuxman
2

Esto copiará los archivos normales y ocultos, al tiempo que excluye el directorio principal ( ..):

cd /directory/to/copy
cp -r * .[^.]* /destination/directory

Si no excluye el directorio principal, también terminará con todo el contenido de ..su directorio de destino.

mch
fuente
1
Pero esto aún excluye los nombres que comienzan con .. (por ejemplo, ...o ..super-hidden).
Scott
0

Para copiar archivos que comienzan con un punto, simplemente haga cp. * Target /

Tan fácil es hacer el comando cp dos veces.

Como dice Peter Eisentraut, las reglas normales de globbing no incluyen ... y. (hm, ¿cómo terminar esta oración?;)

Simplemente use -r para hacerlo recursivo y -i para hacer que cp pregunte si realmente desea sobrescribir un archivo.

cp -ri /backup/olduser/* /newuser/
cp -ri /backup/olduser/.* /newuser/
gaqzi
fuente
Por *lo general , no coincide .o .., pero lo hace si lo usa .*. Tratar echo .*. Puede excluir .y ..con el siguiente patrón: .[^.]*.
mch
@mch: pero .[^.]*aún excluye los nombres que comienzan con .. (por ejemplo, ...o ..super-hidden).
Scott
0

Esto funciona para copiar todos los archivos y directorios, excepto los directorios ocultos recursivamente desde el directorio actual a donde sea:

cp -rf * ^.* 
Seeeve
fuente