Answers:
diff -r dir1 dir2 | grep dir1 | awk '{print $4}' > difference1.txt
说明:
diff -r dir1 dir2
显示哪些文件仅在dir1中,哪些仅在dir2中,以及两个目录中存在的文件的更改(如果有)。
diff -r dir1 dir2 | grep dir1
显示哪些文件仅在dir1中
awk
仅打印文件名。
$4
举个例子。实际上,在我实际的Ubuntu上,diff
用意大利语答复。$4
可以接受意大利语和英语的回复,但是我不确定其他所有语言都可以使用…
diff -rq dir1 dir2 | grep 'Only in dir1/'
-q
选项:手册页仅说“仅输出文件是否不同”,而不是如何检查它们是否不同。我仔细阅读了源代码,发现它仅检查文件大小来确定差异,而不是实际内容。
-q
选项,我无法重现它仅检查文件大小。使用GNU Diffutils 3.7将两个文件大小相同但内容不同的文件与diff -q file1 file2
输出进行比较Files file1 and file2 differ
。
comm -23 <(ls dir1 |sort) <(ls dir2|sort)
该命令将为您提供位于dir1 而非 dir2中的文件。
关于<( )
符号,您可以将其搜索为“流程替换”。
(ls -R dir1|sort)
可以解决问题
(ls -R dir|sort)
。
vimdiff <(ls dir1 |sort) <(ls dir2|sort)
一个好办法做到这一点比较是使用find
与md5sum
,那么diff
。
例:
使用find
到列表中的所有目录中的文件,然后计算出每个文件和管道到一个文件的MD5哈希:
find /dir1/ -type f -exec md5sum {} \; > dir1.txt
对另一个目录执行相同的步骤:
find /dir2/ -type f -exec md5sum {} \; > dir2.txt
然后将结果两个文件与“ diff”进行比较:
diff dir1.txt dir2.txt
当要比较的两个目录不在同一台计算机上并且您需要确保两个目录中的文件相等时,此策略非常有用。
完成这项工作的另一个好方法是使用git
git diff --no-index dir1/ dir2/
最好的祝福!
Meld(http://meldmerge.org/)在比较目录和其中的文件方面做得很好。
我对所有答复都不满意,因为大多数答复工作非常缓慢,并且对于大型目录产生不必要的冗长输出,因此我编写了自己的Python脚本来比较两个文件夹。
与许多其他解决方案不同,它不比较文件的内容。此外,它不会进入另一个目录中缺少的子目录内。因此输出非常简洁,脚本运行很快。
#!/usr/bin/env python3
import os, sys
def compare_dirs(d1: "old directory name", d2: "new directory name"):
def print_local(a, msg):
print('DIR ' if a[2] else 'FILE', a[1], msg)
# ensure validity
for d in [d1,d2]:
if not os.path.isdir(d):
raise ValueError("not a directory: " + d)
# get relative path
l1 = [(x,os.path.join(d1,x)) for x in os.listdir(d1)]
l2 = [(x,os.path.join(d2,x)) for x in os.listdir(d2)]
# determine type: directory or file?
l1 = sorted([(x,y,os.path.isdir(y)) for x,y in l1])
l2 = sorted([(x,y,os.path.isdir(y)) for x,y in l2])
i1 = i2 = 0
common_dirs = []
while i1<len(l1) and i2<len(l2):
if l1[i1][0] == l2[i2][0]: # same name
if l1[i1][2] == l2[i2][2]: # same type
if l1[i1][2]: # remember this folder for recursion
common_dirs.append((l1[i1][1], l2[i2][1]))
else:
print_local(l1[i1],'type changed')
i1 += 1
i2 += 1
elif l1[i1][0]<l2[i2][0]:
print_local(l1[i1],'removed')
i1 += 1
elif l1[i1][0]>l2[i2][0]:
print_local(l2[i2],'added')
i2 += 1
while i1<len(l1):
print_local(l1[i1],'removed')
i1 += 1
while i2<len(l2):
print_local(l2[i2],'added')
i2 += 1
# compare subfolders recursively
for sd1,sd2 in common_dirs:
compare_dirs(sd1, sd2)
if __name__=="__main__":
compare_dirs(sys.argv[1], sys.argv[2])
用法示例:
user@laptop:~$ python3 compare_dirs.py dir1/ dir2/
DIR dir1/out/flavor-domino removed
DIR dir2/out/flavor-maxim2 added
DIR dir1/target/vendor/flavor-domino removed
DIR dir2/target/vendor/flavor-maxim2 added
FILE dir1/tmp/.kconfig-flavor_domino removed
FILE dir2/tmp/.kconfig-flavor_maxim2 added
DIR dir2/tools/tools/LiveSuit_For_Linux64 added
或者,如果您只想查看第一个目录中的文件:
user@laptop:~$ python3 compare_dirs.py dir2/ dir1/ | grep dir1
DIR dir1/out/flavor-domino added
DIR dir1/target/vendor/flavor-domino added
FILE dir1/tmp/.kconfig-flavor_domino added
PS:如果需要比较文件大小和文件哈希值以进行潜在更改,我在这里发布了更新的脚本:https : //gist.github.com/amakukha/f489cbde2afd32817f8e866cf4abe779
另一种方法(对于大型目录可能更快):
$ find dir1 | sed 's,^[^/]*/,,' | sort > dir1.txt && find dir2 | sed 's,^[^/]*/,,' | sort > dir2.txt
$ diff dir1.txt dir2.txt
由于Erik的post,该sed
命令删除了第一个目录组件)
find
注释而不是单独的答案): cd dir2; find . -exec [ -e ../dir1/{} ] \; -o -print 2>/dev/null
这将打印dir2中存在的文件,但dir1中不存在的文件。
这有点晚了,但可能会对某人有所帮助。不确定diff或rsync是否仅以这种裸格式吐出文件名。感谢plhn提供了很好的解决方案,我在下面进行了扩展。
如果只需要文件名,那么以干净的格式复制所需的文件很容易,则可以使用find命令。
comm -23 <(find dir1 | sed 's/dir1/\//'| sort) <(find dir2 | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'
假定dir1和dir2都在同一父文件夹中。sed只是删除了父文件夹,因此您可以将苹果与苹果进行比较。最后一个sed仅将dir1名称放回去。
如果只需要文件:
comm -23 <(find dir1 -type f | sed 's/dir1/\//'| sort) <(find dir2 -type f | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'
对于目录类似:
comm -23 <(find dir1 -type d | sed 's/dir1/\//'| sort) <(find dir2 -type d | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'
cd
之前find
使用sed
,而不必使用,例如:comm -23 <(cd dir1 || exit; find -type f | sort) <(cd dir2 || exit; find -type f | sort)
。(exit
这里的s可以防止find
使用当前目录cd
失败。)
comm
带有支持的最新版本-z
(带有git.savannah.gnu.org/cgit/coreutils.git/commit/…),则可以执行此操作comm -23 -z <(cd dir1 && find -type f -print0 | sort -z) <(cd dir2 && find -type f -print0 | sort -z)
。(与此同时,我也发现exit
s可以替换。)
此答案通过添加-D
选项来优化@ Adail-Junior的建议之一,这在两个比较目录都不是git存储库的情况下很有用:
git diff -D --no-index dir1/ dir2/
如果使用-D
,就不会看到与的比较/dev/null
:
text
Binary files a/whatever and /dev/null differ
这是bash脚本,用于打印用于同步两个目录的命令
dir1=/tmp/path_to_dir1
dir2=/tmp/path_to_dir2
diff -rq $dir1 $dir2 | sed -e "s|Only in $dir2\(.*\): \(.*\)|cp -r $dir2\1/\2 $dir1\1|" | sed -e "s|Only in $dir1\(.*\): \(.*\)|cp -r $dir1\1/\2 $dir2\1|"
grep
对某事像^dir1
,以确保我没有得到一个dir1
后来出现在该路径。