Copie solo archivos normales de un directorio a otro

12

Me gustaría copiar un contenido del directorio 1 al directorio 2. Sin embargo, me gustaría copiar solo archivos (y no directorios) de mi directorio 1. ¿Cómo puedo hacer eso?

cp dir1/* dir2/*

entonces todavía tengo el problema de los directorios.

Además, todos mis archivos no tienen ninguna extensión, entonces . no hará el truco

usuario1058398
fuente
1
No sé qué extensiones tienen que ver con eso.
ctrl-alt-delor
1
cp dir1/* dir2ocp -t dir2 dir1/*
ctrl-alt-delor
@richard Hay un hábito bastante común proveniente del mundo de DOS de no usar extensiones para directorios, que aún sobrevive en cierta medida, lo que lleva a algunas personas a suponer que si hay un punto, entonces no es un directorio y viceversa.
Gilles 'SO- deja de ser malvado'
ok pero aun no es relevante.
ctrl-alt-delor

Respuestas:

18
cp dir1/* dir2

cpno copiará directorios a menos que se le indique explícitamente que lo haga (con, --recursivepor ejemplo, ver man cp).

Nota 1: cp lo más probable es que salga con un estado distinto de cero, pero los archivos se habrán copiado de todos modos. Esto puede ser un problema cuando el encadenamiento de comandos basado en códigos de salida: &&, ||, if cp -r dir1/* dir2; then ..., etc (Gracias a contrebis para su comentario sobre esta cuestión )

Nota 2 : cpespera que el último parámetro sea un único nombre de archivo o directorio. Realmente no debería haber ningún comodín *después del nombre del directorio de destino. dir2\*será expandido por el shell al igual que dir1\*. Cosas inesperadas van a suceder:

  • Si dir2está vacío y depende de su shell y configuración:
    • es posible que reciba un mensaje de error, que es el mejor de los casos.
    • dir2/*se tomará literalmente (buscando un archivo / directorio llamado *), lo que probablemente también conducirá a un error, a menos que *realmente exista.
    • dir2/*simplemente se eliminará del comando por completo, dejando cp dir1/*. Lo cual, dependiendo de la expansión de dir1/*, incluso puede destruir datos:
      • Si dir1/*solo coincide con un archivo o directorio, obtendrá un error de cp.
      • Si dir1/*coincide exactamente con dos archivos, uno será sobrescrito por el otro ( Malo ).
      • Si dir/*coincide con varios archivos y la última coincidencia es a, recibirá un mensaje de error.
      • Si la última coincidencia de dir/*es un directorio, todas las demás coincidencias se moverán a él.
  • Si dir2no está vacío, nuevamente depende de:
    • Si la última coincidencia de dir2/*es un directorio, dir1/*y las otras coincidencias de dir2/*se moverán a.
    • Si la última coincidencia de dir2/*es un archivo, probablemente recibirá un mensaje de error, a menos que dir1/* solo coincida con un archivo.
Adaephon
fuente
$ cp dir1/* dir2-> cp: dir1/isadir is a directory (not copied).salidas con estado 1 para mí.
contrebis
1
Sí, también sale con el estado 1 para mí. Pero aun así, cpcopia los archivos que coinciden dir1/*en cada sistema que verifiqué: Arch Linux, Ubuntu 14.04, OpenBSD 3.9 y 5.5, SuSE Linux 8.1, FreeBSD 6.2, Solaris 8, 9 y 10 (donde en cprealidad sale con el código 2). Por lo tanto, este comportamiento no es nuevo (SuSE 8.1 es de 2002) ni está limitado a Linux. cpsale con un código de salida distinto de cero porque no podía hacer todo lo que le dijeron que hiciera. Eso no significa que no haga nada .
Adaephon
3
Claro, pensé que valía la pena señalarlo porque si estás encadenando comandos junto con &&esto, puedes causar un problema. Estaba tratando de hacer algo como esto, aunque no puedo recordar el contexto ahora.
contrebis
Esto no copia archivos ocultos.
Felwithe
@felwithe Si *incluye archivos ocultos o cómo incluir archivos ocultos depende del shell. Si *no incluye archivos ocultos, puede asociarlos con .*. Tenga en cuenta que esto incluirá .y ..en bashy dash, pero no en zsh. En el contexto de esta respuesta puede salirse con la cp dir1/* dir1/.* dir2causa .y ..son directorios y no será copiado. zshTambién se puede hacer que incluya archivos ocultos con *(D).
Adaephon
7

Es el shell que expande los comodines, no los comandos. Entonces, cp dir1/* dir2/*primero expande los dos comodines, luego llama cpal resultado. Esto no es en absoluto lo que aparentemente espera: dependiendo de cuántos archivos ya haya dir2, dir2/*puede expandirse a uno o más argumentos. El comando cpno sabe cuáles de sus argumentos provienen de expandir el primer patrón y cuáles provienen de expandir el segundo patrón. Espera que su último argumento sea el nombre del directorio de destino. Por lo tanto, para copiar todos los archivos del directorio dir1en el directorio dir2, el último argumento debe ser el directorio dir2:

cp dir1/* dir2

Como *coincide con todos los archivos, cpintenta copiar todos los archivos. Esto incluye directorios: los directorios también son archivos. Se salta los directorios, pero informa un error. Copia el contenido de archivos especiales como las canalizaciones con nombre (es mejor que algo les escriba o cpbloquee), etc.

Para copiar solo archivos normales , debe restringir la coincidencia. En zsh, puede usar el calificador glob . para eso:

cp dir1/*(.) dir2

Otras conchas no tienen esto. Puede usar el findcomando para filtrar los tipos de archivo. Suponiendo que esté ejecutando Linux o Cygwin no incrustado:

find dir1 -maxdepth 1 -type f -exec cp -t dir2 {} +

En Linux, FreeBSD y OSX:

find dir1 -maxdepth 1 -type f | xargs -I {} cp {} dir2
Gilles 'SO- deja de ser malvado'
fuente
¿Hay alguna razón para especificar -maxdepth 1? Además, ¿hay alguna manera de copiar y preservar recursivamente la jerarquía de directorios original en el directorio de destino?
Abdull
@Abdull Sin -maxdepth 1, el findcomando volvería a aparecer en subdirectorios, que no se deseaban aquí. Si desea copiar todo el árbol de directorios incluyendo los subdirectorios, que es una cuestión totalmente diferente, y la respuesta es mucho más simple: cp -a dir1 dir2.
Gilles 'SO- deja de ser malvado'
0

A continuación se muestra el comando para copiar el archivo del directorio de origen al de destino.

  1. Vaya a la carpeta de origen y luego escriba el siguiente comando:

    $ cp fileName destination directory path

Ejemplo:

cp publichOT.sh  /data/home/useradmin
Tapan Dubey
fuente