Surpreendentemente, nenhuma resposta em 6 anos usa a -i
opção ou fornece resultados agradáveis, então aqui vou eu:
TLDR - Apenas me mostre os comandos
rsync -rin --ignore-existing "$LEFT_DIR"/ "$RIGHT_DIR"/|sed -e 's/^[^ ]* /L /'
rsync -rin --ignore-existing "$RIGHT_DIR"/ "$LEFT_DIR"/|sed -e 's/^[^ ]* /R /'
rsync -rin --existing "$LEFT_DIR"/ "$RIGHT_DIR"/|sed -e 's/^/X /'
Entendendo a saída
Aqui está um exemplo da saída:
L file-only-in-Left-dir
R file-only-in-right-dir
X >f.st...... file-with-dif-size-and-time
X .f...p..... file-with-dif-perms
Observe o primeiro caractere de cada linha:
L
/ R
significa que o arquivo / dir aparece apenas no diretório L
eft ou R
ight.
X
significa que o arquivo aparece em ambos os lados, mas não é o mesmo (caso em que os próximos 11 caracteres dar mais informações. s
, t
e p
detectar diferenças nas s ize, t ime e p ermissions respectivamente - para mais informações tentar man rsync
e procurar --itemize-changes
) .
Opções extras que você pode querer usar
Se você também quiser comparar o proprietário / grupo / permissões dos arquivos, adicione as opções -o
/ -g
/ -p
respectivamente. Por fim, observe que, por padrão, o rsync considera dois arquivos iguais, se eles tiverem o mesmo nome, hora e tamanho. Isso é extremamente rápido e, na maioria das vezes, mais do que suficiente, mas se você quiser ter 100% de certeza, adicione -c
também para comparar o conteúdo dos arquivos com o mesmo nome, hora e tamanho.
TLDR - Apenas me dê um script para ligar
Aqui está. Chame assim
diff-dirs Left_Dir Right_Dir [options]
Todas as opções mencionadas acima na seção "Opções extras que você deseja usar" também se aplicam aqui.
#!/bin/bash
# Compare two directories using rsync and print the differences
# CAUTION: options MUST appear after the directories
#
# SYNTAX
#---------
# diff-dirs Left_Dir Right_Dir [options]
#
# EXAMPLE OF OUTPUT
#------------------
# L file-only-in-Left-dir
# R file-only-in-right-dir
# X >f.st...... file-with-dif-size-and-time
# X .f...p..... file-with-dif-perms
#
# L / R mean that the file/dir appears only at the `L`eft or `R`ight dir.
#
# X means that a file appears on both sides but is not the same (in which
# case the next 11 characters give you more info. In most cases knowing
# that s,t,T and p depict differences in Size, Time and Permissions
# is enough but `man rsync` has more info
# (look at the --itemize-changes option)
#
# OPTIONS
#---------
# All options are passed to rsync. Here are the most useful for the purpose
# of directory comparisons:
#
# -c will force comparison of file contents (otherwise only
# time & size is compared which is much faster)
#
# -p/-o/-g will force comparison of permissions/owner/group
if [[ -z $2 ]] ; then
echo "USAGE: $0 dir1 dir2 [optional rsync arguments]"
exit 1
fi
set -e
LEFT_DIR=$1; shift
RIGHT_DIR=$1; shift
OPTIONS="$*"
# Files that don't exist in Right_Dir
rsync $OPTIONS -rin --ignore-existing "$LEFT_DIR"/ "$RIGHT_DIR"/|sed -e 's/^[^ ]* /L /'
# Files that don't exist in Left_Dir
rsync $OPTIONS -rin --ignore-existing "$RIGHT_DIR"/ "$LEFT_DIR"/|sed -e 's/^[^ ]* /R /'
# Files that exist in both dirs but have differences
rsync $OPTIONS -rin --existing "$LEFT_DIR"/ "$RIGHT_DIR"/|sed -e 's/^/X /'
Como funciona?
Estamos chamando o rsync assim:
rsync -rin ...
Usamos -i
( --itemize-changes
) para dizer ao rsync para imprimir uma linha de saída para cada arquivo que contém informações sobre quaisquer diferenças entre os dois diretórios. Precisamos -n
suprimir o comportamento normal do rsync (que é tentar sincronizar os dois diretórios, copiando / excluindo arquivos). também precisamos -r
trabalhar recursivamente para todos os arquivos / subdiretórios.
Chamamos rsync três vezes:
1ª chamada : imprima arquivos que não existem no Dir_B. Precisamos usar --ignore-existing
para ignorar arquivos que existem nos dois lados.
rsync -rin --ignore-existing $DIR_A/ $DIR_B/
2ª chamada : exatamente como antes, mas trocamos a ordem de DIR_A / DIR_B.
3ª chamada : Finalmente, usamos --existing
apenas para verificar os arquivos que aparecem nos dois diretórios.
rsync -rin --existing $DIR_A/ $DIR_B/