Пример
Предположим, у меня есть 2 каталога a/
и b/
. Допустим, они содержат следующие файлы:
a/
a/foo/1
a/bar/2
a/baz/3
b/
b/foo/1
b/bar/2
такие, что a/foo/1
и b/foo/1
идентичны, но a/bar/2
и b/bar/2
различны.
После слияния a/
в b/
я хочу получить:
a/
a/bar/2
b/
b/foo/1
b/bar/2
b/baz/3
Объяснение
a/foo/
иb/foo/
(рекурсивно) идентичны, поэтому мы удаляемa/foo/
.a/bar/2
иb/bar/2
отличаются, поэтому мы ничего не делаем.a/baz/
существует только в ,a/
но не вb/
, поэтому мы перемещаем его вb/baz/
.
Есть ли готовая команда оболочки для этого? У меня есть ощущение, что это rsync
может сработать, но я не знаком с rsync
.
решение1
Не могу сказать, что знаю конкретную команду, которая сделает это за вас. Но вы можете сделать это, просто используя хеширование.
Наивный пример ниже:
#!/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
Это определенно можно сделать чище, особенно если вас интересуют только файлы с идентичными путями друг к другу. Также, вероятно, можно сделать за линейное время, но общая концепция будет работать.