2

如何将所有唯一文件从两个源文件夹复制到新的目标文件夹?

作为一组操作:如何计算两个文件夹之间的差异?

4

4 回答 4

3

你可以试试这个:

cd <First Dir>
find . > /tmp/first.dat
cd <Second Dir>
find . > /tmp/second.dat
comm -23 /tmp/first.dat /tmp/second.dat | while read line; do cp <First Dir>/$line <New Dir> ; done
comm -13 /tmp/first.dat /tmp/second.dat | while read line; do cp <SecondDir>/$line <New Dir> ; done
于 2012-03-22T08:54:38.510 回答
1

我敢肯定还有其他方法(这里没有建议的额外文件操作),但这是一种相对简单的方法来完成此操作。

假设:
A1) 只对文件夹的直接内容感兴趣。
A2) 假定同名文件具有相同的内容。

1) 创建/使用一个空的临时目录 (tmp)
2) 将 sourceDir1 的内容复制到 tmp
3) 从 tmp 中删除 sourceDir2 的内容
-- 现在您在 tmp 中拥有 sourceDir1 的唯一文件
4) 将 tmp 的内容移动到所需位置
5) 重复步骤 2)-4) 交换 sourceDir1 和 sourceDir2 的角色

注意:
N1)您可以使用ls列出文件(或目录),并将其重定向到文件(例如 s1.tmp)。然后你可以通过使用比较其他文件夹的文件(目录)列表,grep查看当前文件(目录)是否在s1.tmp中列出。您可以使用此技术来计算要输入哪些目录以进行递归处理(从而放松 A1)。
N2)如果有问题的文件是文本文件,您可以使用 diff 来查看它们是否相同。如果是,请照常处理,否则适当处理相同文件名、不同内容的情况(例如,使用唯一扩展名将两个文件复制到目标目录以指示其来源——这里的逻辑取决于您的目标)。
N3)您显然也可以比较二进制文件,请参阅stackoverflow#4013223超级用户#135911

于 2012-03-21T14:52:53.587 回答
1

要从foo/和复制所有文件bar/baz/最简单的方法就是复制两者,并让其中一个覆盖另一个:

cp --recursive foo/ baz/
cp --recursive bar/ baz/

如果您想更清洁一点,而不是bar/从中存在的任何内容中复制foo/,您可以编写:

cp --recursive foo/ baz/
( cd bar/
  find -exec bash -c ' if ! [[ -e ../foo/"{}" ]] ; then
                         cp "{}" ../baz/"{}"
                       fi
                     ' \;
)

您可以使用相同的方法生成其中bar/不存在的文件列表foo/

( cd bar/
  find -exec bash -c ' if ! [[ -e ../foo/"{}" ]] ; then
                         echo bar/"{}"
                       fi
                     ' \;
)

(或者您可以更改echo bar/"{}"printf %s\0 bar/"{}"使用零值字节而不是换行符作为分隔符)。

或者,对于某些种类,您可以编写:

diff --old-line-format=%L --new-line-format= --unchanged-line-format= \
     <( cd foo/ ; find | sort ) <( cd bar/ ; find | sort )

它将cd foo/ ; find | sortcd bar/ ; find | sort的输出diff作为输入文件传递,并告诉diff打印在第一个输入文件中找到的行并丢弃其他所有内容。(注意:如果任何文件名包含换行符,这将中断。)

以上都没有比较不同文件的内容,只是因为我不确定如果它们不同应该怎么做。检查文件内容可以diff -r -q foo/ bar/作为一个起点,但我们该怎么做呢?

于 2012-03-21T19:21:52.533 回答
0

起初,我以为我可以通过巧妙地使用来解决这个问题,rsync但没有任何效果。

所以我的最终解决方案是一个小的Python 脚本 (gist)

于 2012-03-22T11:18:34.093 回答