Exemplo
Suponha que eu tenha 2 diretórios a/
e b/
. Digamos que eles contenham os seguintes arquivos:
a/
a/foo/1
a/bar/2
a/baz/3
b/
b/foo/1
b/bar/2
de modo que a/foo/1
e b/foo/1
são idênticos, mas a/bar/2
e b/bar/2
são diferentes.
Depois de mesclar a/
, b/
quero obter:
a/
a/bar/2
b/
b/foo/1
b/bar/2
b/baz/3
Explicação
a/foo/
eb/foo/
são (recursivamente) idênticos, então removemosa/foo/
.a/bar/2
eb/bar/2
são diferentes, então não fazemos nada.a/baz/
existe apenas em,a/
mas não emb/
, então o movemos parab/baz/
.
Existe um comando shell pronto para isso? Tenho a sensação de que rsync
pode funcionar, mas não estou familiarizado com o rsync
.
Responder1
Não posso dizer que conheço um comando específico que faria isso por você. Mas você poderia conseguir isso apenas usando hash.
Exemplo ingênuo abaixo:
#!/bin/bash
# ...some stuff to get the files...
# Get hashes for all source paths
for srcFile in "${srcFileList[@]}"
do
srcHashList+="$(md5sum "$srcFile")"
done
# Get hashes for all destination paths
for dstFile in "${dstFileList[@]}"
do
dstHashList+="$(md5sum "$dstFile")"
done
# Compare hashes, exclude identical files, regardless of their path.
for srci in "${!srcHashList[@]}"
do
for dsti in "${!dstHashList[@]}"
do
match=0
if [ "${srcHashList[$srci]}" == "${dstHashList[$dsti]}" ]
then
match=1
fi
if [ $match != 1 ]
then
newSrcList+=${srcFileList[$srci]}
newDstList+=${dstFileList[$dsti]}
fi
done
done
# ...move files after based on the new lists
Definitivamente, isso poderia ser feito de forma mais limpa, especialmente se você se preocupa apenas com arquivos com caminhos idênticos entre si. Provavelmente também poderia ser feito em tempo linear, mas o conceito geral funcionará.