2010-12-31 12 views
52

Estoy buscando un script de shell que combine archivos de un directorio a otro.¿Cómo combino un directorio en otro usando Bash?

muestra:

html/ 
    a/ 
    b.html 
    index.html 

html_new/ 
    a/ 
    b2.html 
    b.html 

Uso:

./mergedirs.sh html html_new 

Resultado:

html/ 
    a/ 
    b.html 
    b2.html 
    index.html 

html/a/b.html fue reemplazado por html_new/a/b.html
html/a/b2.html fue copiado de
html/index.html se mantuvo intacta

+1

Probado 'cp -r html_new/* html'? Puede eliminar el directorio 'html_new' luego. – ismail

Respuesta

61

Probablemente solo desee cp -R $1/* $2/ - es una copia recursiva.

(si puede haber archivos ocultos (aquellos cuyos nombres comienzan con un punto), debe prefijo que comando con shopt -s dotglob; para asegurarse de que quedan emparejados.)

2

¿No cp -r trabajo?

cp -r html_new/* html 

o (desde la primera versión no copiará ".something" archivos)

cd html_new; cp -r . ../html 

Tenga en cuenta que -rlee de tuberías si alguno de los archivos en el directorio copiado son tuberías . Para evitar eso, use -R en su lugar.

+0

Al "fusionar" múltiples directorios, etc., considere también la opción '-n' (no clobber) o' -f' (force) para conservar los archivos existentes o sobrescribirlos. –

2
cd html 
cp -r . /path/to/html_new 
13

Tome un rsync mirada att

rsync --recursive html/ html_new/ 

rsync tiene un montón de banderas para establecer a fin de buscar en la página de manual de rsync para más detalles

56
cp -RT source/ destination/ 

Todos los archivos y directorios en source va a terminar en destination. Por ejemplo, source/file1 se copiará al destination/file1.

El indicador -T detiene source/file1 para que se copie en destination/source/file1.

+0

funciona bien, copia y combina/carpeta/datos a carpeta2/datos – wiak

+1

Considero esta solución porque funciona "tal cual" con archivos .dot. – fnkr

5

Simplemente use rsync - es una gran herramienta para la copia de archivos locales & fusión además de la copia remota.

rsync --av/ruta/a/source_folder// ruta/a/destination_folder/

Tenga en cuenta que la barra final en la carpeta de origen es necesario copiar sólo el contenido de source_folder al destino-si desactívelo, copiará la carpeta origen y sus contenidos, probablemente no lo que está buscando ya que desea unir carpetas.

+0

hay un pequeño error de tipeo, guión adicional, por lo que debe ser 'rsync -av/ruta/a/carpeta_origen// ruta/a/carpeta_destino /' – vim

1

Aunque esta pregunta y su respuesta aceptada son antiguas, agrego mi respuesta porque las que existen actualmente que usan cp o bien no manejan algunos casos extremos o requieren trabajar de forma interactiva. Sin embargo, a menudo no importan los casos de borde/guión/portabilidad/fuentes múltiples, en cuyo caso la simplicidad gana, y es mejor usar cp directamente con menos banderas (como en otras respuestas) para reducir la carga cognitiva, pero para aquellos otras veces (o para una función robustamente reutilizable) esta invocación/función es útil, y por cierto no es específica de bash (me doy cuenta de que esta pregunta era sobre bash, así que eso es solo una bonificación en este caso). Algunos indicadores se pueden abreviar (por ejemplo, con -a), pero he incluido todos explícitamente en formato largo (excepto en el -R, consulte a continuación) por razones de explicación. Obviamente, simplemente elimine cualquier indicador si hay alguna característica que usted no desea desea (o si está en un sistema operativo que no es POSIX, o su versión de cp no procesa ese indicador - He probado esto en GNU coreutils 8.25 cp):

mergedirs() { 
    _retval=0 
    _dest="$1" 
    shift 
    yes | \ 
     for _src do 
      cp -R --no-dereference --preserve=all --force --one-file-system \ 
        --no-target-directory "${_src}/" "$_dest" || { _retval=1; break; } 
     done 2>/dev/null 
    return $_retval 
} 

mergedirs destination source-1 [source-2 source-3 ...] 

Explicación:

  • -R: tiene sutilmente diferentes semántica de -r/--recursive en algunos sistemas (en particular con respecto a los archivos especiales en dirs fuente) como se explica en this answer
  • --no-dereference: Nunca seguir enlaces simbólicos en FUENTE
  • --preserve=all: preservar los atributos especificados (por defecto: modo, propiedad, marcas de tiempo), si es posible, atributos adicionales: contexto, enlaces, xattr, todo
  • --force: si una ya existente archivo de destino no se puede abrir, retire y vuelva a intentarlo
  • --one-file-system: permanecer en este sistema de archivos
  • --no-target-directory: DEST tratar como un archivo normal (explicado en en this answer, a saber: If you do a recursive copy and the source is a directory, then cp -T copies the content of the source into the destination, rather than copying the source itself.)
  • [entrada de hilo de yes]: incluso con --force, en este modo recursivo particular, cp todavía pregunta antes clobbering cada archivo, por lo que lograr la no-interactividad mediante la canalización de salida de yes a ella
  • [salida de hilo a /dev/null]: este es silenciar la cadena desordenada de preguntas a lo largo de las líneas de cp: overwrite 'xx'?
  • [para volver-val & salida temprana]: esto asegura el bucle sale tan pronto como hay una copia fallado, y devuelve 1 si hubo un error

BTW:

  • Una nueva bandera cobarde que también utilizo con esto en mi sistema es --reflink=auto para hacer llamadas "copias de luz" (copia en escritura, con las mismas ventajas de velocidad como difíciles de vinculación, y el mismo el tamaño beneficia hasta y en proporción inversa a la cantidad de archivos divergentes en el futuro). Esta bandera es aceptada en el reciente GNU cp, y hace más que un no-op con sistemas de archivos compatibles en kernels recientes de Linux. YMWV-a-lot en otros sistemas.
Cuestiones relacionadas