比较两个文件夹并将唯一条目复制/链接到新文件夹

时间:2012-03-21 14:26:10

标签: bash scripting set-operations

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

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

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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#4013223superuser#135911

答案 2 :(得分: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打印仅找到的行< / em>在第一个输入文件中并丢弃其他所有内容。 (注意:如果任何文件名包含换行符,则会中断。)

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

答案 3 :(得分:0)

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

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