Linux

如何在不覆蓋具有相同相對路徑的不同文件的情況下合併 2 個目錄?

  • January 20, 2022

例子

假設我有 2 個目錄a/b/. 假設它們包含以下文件:

a/
a/foo/1
a/bar/2
a/baz/3

b/
b/foo/1
b/bar/2

這樣a/foo/1b/foo/1是相同的,但a/bar/2b/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/.

有現成的shell命令嗎?我有一種感覺rsync可能會奏效,但我不熟悉rsync.

不能說我知道可以為您執行此操作的特定命令。但是您可以僅使用散列來完成此操作。

下面的天真範例:

#!/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

這絕對可以做得更乾淨,特別是如果您只關心彼此具有相同路徑的文件。也可以線上性時間內完成,但一般概念會起作用。

引用自:https://unix.stackexchange.com/questions/652593