GNU/Linux >> Tutoriales Linux >  >> Linux

¿Alguna forma de sincronizar la estructura del directorio cuando los archivos ya están en ambos lados?

Tengo dos unidades con los mismos archivos, pero la estructura de directorios es totalmente diferente.

¿Hay alguna forma de "mover" todos los archivos en el lado de destino para que coincidan con la estructura del lado de origen? ¿Quizás con un guión?

Por ejemplo, la unidad A tiene:

/foo/bar/123.txt
/foo/bar/234.txt
/foo/bar/dir/567.txt

Mientras que la unidad B tiene:

/some/other/path/123.txt
/bar/doo2/wow/234.txt
/bar/doo/567.txt

Los archivos en cuestión son enormes (800 GB), por lo que no quiero volver a copiarlos; Solo quiero sincronizar la estructura creando los directorios necesarios y moviendo los archivos.

Estaba pensando en una secuencia de comandos recursiva que encontraría cada archivo de origen en el destino, luego lo movería a un directorio coincidente y lo crearía si fuera necesario. Pero, ¡eso está más allá de mis habilidades!

Aquí se proporcionó otra solución elegante:
https://superuser.com/questions/237387/any-way-to-sync-directory-structure-when-the-files-ya-are-on-both-sides /238086

Respuesta aceptada:

Iré con Gilles y te indicaré Unison como lo sugirió hasen j. Unison fue DropBox 20 años antes que DropBox. Código sólido como una roca que mucha gente (incluido yo mismo) usa todos los días; vale la pena aprenderlo. Aún así, join necesita toda la publicidad que pueda conseguir 🙂

Esta es solo la mitad de una respuesta, pero tengo que volver al trabajo 🙂

Básicamente, quería demostrar el poco conocido join utilidad que hace exactamente eso:une dos tablas en un campo.

Primero, configure un caso de prueba que incluya nombres de archivos con espacios:

for d in a b 'c c'; do mkdir -p "old/$d"; echo $RANDOM > "old/${d}/${d}.txt"; done
cp -r old new

(edite algunos directorios y/o nombres de archivos en new ).

Ahora, queremos construir un mapa:hash -> nombre de archivo para cada directorio y luego usar join para unir archivos con el mismo hash. Para generar el mapa, coloque lo siguiente en makemap.sh :

find "$1" -type f -exec md5 -r "{}" ; 
  | sed "s/([a-z0-9]*) ${1}/(.*)/1 "2"/" 

makemap.sh escupe un archivo con líneas de la forma, 'hash "nombre de archivo"', por lo que simplemente nos unimos en la primera columna:

join <(./makemap.sh 'old') <(./makemap.sh 'new') >moves.txt

Esto genera moves.txt que se ve así:

49787681dd7fcc685372784915855431 "a/a.txt" "bar/a.txt"
bfdaa3e91029d31610739d552ede0c26 "c c/c c.txt" "c c/c c.txt"

El siguiente paso sería hacer los movimientos, pero mis intentos se atascaron al citar... mv -i y mkdir -p debería ser útil.

Relacionado:¿cómo glob todos los archivos ocultos excepto el directorio actual y principal?
Linux
  1. ¿Cuál es la mejor manera de contar el número de archivos en un directorio?

  2. ¿Hay alguna manera de hacer que mv cree el directorio al que se moverá si no existe?

  3. ¿Cómo tardo un directorio sin conservar la estructura del directorio?

  4. Linux:compare la estructura de directorios sin comparar archivos

  5. ¿Cuáles son las diferencias entre los archivos .txt de Linux y Windows (codificación Unicode)?

Manera de decirle a Logrotate que ignore los archivos abiertos?

¿A dónde van los archivos cuando se emite el comando Rm?

Contando el número de archivos en un directorio usando C

¿Cómo obtener el tamaño real del directorio (fuera de du)?

¿Cuál es la forma más eficiente de mover una gran cantidad de archivos que residen en un solo directorio?

¿Cuál es la forma más rápida de eliminar todos los archivos y subcarpetas de un directorio?