如何将所有唯一文件从两个源文件夹复制到新的目标文件夹?
作为一组操作:如何计算两个文件夹之间的差异?
你可以试试这个:
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
我敢肯定还有其他方法(这里没有建议的额外文件操作),但这是一种相对简单的方法来完成此操作。
假设:
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
要从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 | sort
和cd bar/ ; find | sort
的输出diff
作为输入文件传递,并告诉diff
打印仅在第一个输入文件中找到的行并丢弃其他所有内容。(注意:如果任何文件名包含换行符,这将中断。)
以上都没有比较不同文件的内容,只是因为我不确定如果它们不同应该怎么做。检查文件内容可以diff -r -q foo/ bar/
作为一个起点,但我们该怎么做呢?
起初,我以为我可以通过巧妙地使用来解决这个问题,rsync
但没有任何效果。
所以我的最终解决方案是一个小的Python 脚本 (gist)。