Si uso mv
para mover una carpeta llamada "carpeta" a un directorio que ya contiene "carpeta", ¿se fusionarán o se reemplazarán?
149
mv
no puede fusionar o sobrescribir directorios, fallará con el mensaje "mv: no se puede mover 'a' a 'b': el directorio no está vacío" , incluso cuando está utilizando la --force
opción.
Puede solucionar esto utilizando otras herramientas (como rsync
, find
o incluso cp
), pero debe considerar cuidadosamente las implicaciones:
rsync
puede fusionar el contenido de un directorio en otro (idealmente con la opción --remove-source-files
1 para eliminar de forma segura solo aquellos archivos fuente que se transfirieron con éxito, y con la opción habitual de conservación de permisos / propiedad / tiempo -a
si lo desea) rsync
la --link-dest=DIR
opción (para crear enlaces duros en lugar de copiar el contenido del archivo, cuando sea posible) y --remove-source-files
obtener una semántica muy similar a una regular mv
. --link-dest
se le debe dar una ruta absoluta al directorio de origen (o una ruta relativa desde el destino a la fuente ). --link-dest
de forma no intencionada (lo que puede o no causar complicaciones), requiere conocer (o determinar) la ruta absoluta a la fuente (como argumento para --link-dest
), y nuevamente deja una estructura de directorio vacía para limpiar como por 1 .find
para recrear secuencialmente la estructura del directorio fuente en el destino, luego mover individualmente los archivos reales cp
puede crear enlaces duros (simplemente, punteros adicionales al mismo archivo existente), lo que crea un resultado muy similar a una fusión mv
(y es muy eficiente en IO ya que solo se crean punteros y no hay que copiar datos reales) Cuál de estas soluciones (si las hay) es apropiada dependerá en gran medida de su caso de uso específico.
Como siempre, piense antes de ejecutar cualquiera de estos comandos y realice copias de seguridad.
1: Tenga en cuenta que rsync --remove-source-files
no eliminará ningún directorio, por lo que tendrá que hacer algo como find -depth -type d -empty -delete
después para deshacerse del árbol de directorios de origen vacío.
mv
. Esta respuesta sería mejor con una verdad más amplia. Linux, BSD y Unix "real", o una referencia de POSIX o SUS.mv
implementación utilizada por Debian - el énfasis está en probar , ya que la página de manual no menciona este comportamiento ...--delete
solo elimina archivos en el directorio de destino que no existen en el directorio de origen.-H
función o puede vincular archivos en el destino utilizando--link-dest
. Sin embargo, vea la página de manual antes de usarlos.fuente
--remove-source-files
tiene la ventaja de eliminar solo los archivos que se transfirieron con éxito, por lo que puede usarlosfind
para eliminar directorios vacíos y quedará con todo lo que no se transfirió sin tener que verificarrsync
la salida.Puede usar la
-l
opción del comando cp , que crea enlaces duros de archivos en el mismo sistema de archivos en lugar de copias de datos completos. El siguiente comando copia la carpetasource/folder
a una carpeta principal (destination
) que ya contiene un directorio con el nombrefolder
.También es posible que desee utilizar el
-P
(--no-dereference
- no elimine la referencia de los enlaces simbólicos) o-a
(--archive
- conservar todos los metadatos, también incluye la-P
opción), según sus necesidades.fuente
cp
lugar de hacerlo,rsync
ya que todos los sistemas tienencp
y todos están familiarizados con él.cp
con el tiempo de operación demv
.-n
mv /fs1/file /fs2/
(en todos los sistemas de archivos) realizará una copia y luego una eliminación.mv
funcionará (siempre que el directorio de destino aún no exista), incluso si no es "eficiente" o como se llame,cp -rl
fallará.Recomiendo estos cuatro pasos:
o mejor aún, aquí hay un script que implementa una semántica similar a
mv
:fuente
rsync -u
(solo actualizar si es más reciente),mv
(en algunas versiones al menos) también puede tomar la-u
opción. Sin embargo, en ese caso, es posible que desee eliminar los directorios de origen no vacíos, así como los vacíos, para cubrir los casos en que los archivos en el árbol de origen no son más nuevos. @schuess: Parece que puede haber múltiples argumentos SOURCE, si lo necesita.Aquí hay una forma de combinar los directorios. Es mucho más rápido que rsync ya que solo cambia el nombre de los archivos en lugar de copiarlos y luego eliminarlos.
fuente
dest
ya es un directorio con el mismo nombre que insource
. Y los archivos se moverán a undest
, que está ensource
. El comando no hace más quemv source/* source/dest/.
Una forma de lograr esto sería usar:
Siempre que no haya dos archivos con el mismo nombre
folder
ydirectory/folder
, obtendrá el mismo resultado, es decir, la fusión.fuente
rm folder
?rm folder -fR
siempre funciona para míPara las copias más puras, uso el método tar (-) B blockread copy.
ejemplo, desde dentro de la ruta de origen ('cd' allí si es necesario):
Esto crea una copia exacta del árbol de origen, CON el propietario y los permisos intactos. Y si la carpeta de destino existe, los datos se fusionarán. Solo se sobrescribirán los archivos que ya existen.
Ejemplo:
Cuando la acción de copiar es exitosa, puede eliminar la fuente (
rm -rf <source>
). Por supuesto, este no es un movimiento exacto: los datos se copiarán hasta que elimine la fuente.Como opción, puede ser detallado (mostrar en pantalla el archivo que se está copiando), con -v:
tar cBvf -
c
: crearB
: leer bloque completo (para lectura de tubería)v
: detalladof
: archivo para escribirx
: extracto-
: stdout / stdinsourcefolder
también puede ser*
(para cualquier cosa en la carpeta actual)fuente
f -
tar generalmente no es necesario: el valor predeterminado es leer desde stdin / escribir en stdout.Aquí hay un guión que funcionó para mí. Prefiero mv sobre rsync, así que uso las soluciones de Jewel y Jonathan Mayer.
fuente
No es una buena idea usar comandos como cp o rsync. Para archivos grandes, llevará mucho tiempo. mv es mucho más rápido ya que solo actualiza los inodes sin copiar físicamente los archivos. Una mejor opción es usar el administrador de archivos de su sistema operativo. Para Opensuse, hay un administrador de archivos llamado Konquerer. Puede mover archivos sin copiarlos realmente. Tiene la función "cortar y pegar" como en Windows. Simplemente seleccione todos los subdirectorios en el directorio A. Haga clic derecho y "muévase" al directorio B que puede contener subdirectorios con los mismos nombres. Los fusionará. También hay opciones si desea sobrescribir o renombrar archivos con el mismo nombre.
fuente
mv
se usa.Solución Python
Como no pude encontrar una solución preexistente satisfactoria, decidí hacer un script Python rápido para lograrlo.
En particular, este método es eficiente porque solo recorre el árbol de archivos de origen una vez de abajo hacia arriba.
También le permitirá ajustar rápidamente cosas como el manejo de sobrescritura de archivos a su gusto.
Uso:
moverá todo el contenido
src/*
adest/
ysrc/
desaparecerá.mover-fusionar-directorios
GitHub aguas arriba .
Ver también: https://stackoverflow.com/questions/22588225/how-do-you-merge-two-directories-or-move-with-replace-from-the-windows-command
fuente
Este es el comando para mover archivos y carpetas a otro destino:
Recuerde : el
mv
comando no funcionará si la carpeta es b̲e̲i̲n̲g m̲e̲r̲ge̲d̲ (es decir, ya existe otra carpeta con el mismo nombre en el destino) y d̲e̲s̲t̲i̲n̲a̲t̲i̲o̲n̲ o̲n̲e̲ i̲s̲ n̲o̲t̲ e̲m̲pt̲y .Si la carpeta de destino está vacía, el comando anterior funcionará bien.
Entonces, para fusionar ambas carpetas en cualquier caso,
hágalo en 2 comandos:
O combine ambos como un comando de una sola vez:
fuente