比较和同步两个(巨大的)目录——只考虑文件名

Compare and sync two (huge) directories - consider only filenames

我想在 Linux 中的两个目录之间进行单向同步。一个包含文件,另一个包含 processed 个文件,但具有相同的目录结构和相同的文件名,但某些文件可能丢失。

现在我在做:

cd $SOURCE
find * -type f | while read fname; do
    if [ ! -e "$TARGET$fname" ]
    then
        # process the file and copy it to the target. Create directories if needed.
    fi
done

有效,但速度慢得令人痛苦。 有更好的方法吗?

大约有 50.000.000 个文件,分布在目录和子目录中。每个目录不超过255files/subdirs.

我看了

编辑

有效假设:

假设:

  • 仅对 directory/file 个名称进行比较
  • 我们不关心文件元数据 and/or 属性(例如,大小、所有者、权限、date/time 最后修改等)
  • 我们不关心可能驻留在目标目录中但在源目录中没有匹配文件的文件

我看不出有什么方法可以比较 2x 约 5000 万个条目的列表,但我们可以尝试消除 bash 循环解决方案的逐个条目方法...

一个想法:

# obtain sorted list of all $SOURCE files

srcfiles=$(mktemp)
cd "${SOURCE}"
find * -type f | sort > "${srcfiles}"

# obtain sorted list of all $TARGET files

tgtfiles=$(mktemp)
cd "${TARGET}"
find * -type f | sort > "${tgtfiles}"

# 'comm -23' => extract list of items that only exist in the first file - ${srcfiles}

missingfiles=$(mktemp)
comm -23 "${srcfiles}" "${tgtfiles}" > "${missingfiles}"

# process list of ${SOURCE}-only files

while read -r missingfile
do
    process_and_copy "${missingfile}"
done < "${missingsfiles}"

'rm' -rf "${srcfiles}" "${tgtfiles}" "${missingfiles}"

此解决方案本质上(仍然)是串行的,因此如果 'lot' 丢失文件,则处理所述丢失文件的总时间可能会很可观。

如果有足够的系统资源(cpu、内存、磁盘吞吐量),'faster' 解决方案将着眼于并行化工作的方法,例如:

  • 运行 不同 $SOURCE/$TARGET 子目录上的并行 find/sort/comm/process 线程(如果丢失文件的数量均匀分布在不同的子目录中,可能会很好地工作)或 ...
  • 坚持使用串行 find/sort/commsplit ${missingfiles} 分成块,然后生成单独的 OS 进程到 process_and_copy 不同的块