我正在尝试查找存在于一个目录中但不存在于另一个目录中的文件,我尝试使用此命令:
diff -q dir1 dir2
上述命令的问题是它找到了dir1
但dir2
中的文件以及dir2
中的文件但dir1
中没有的文件,< / p>
我正在尝试查找dir1
中的文件,但不是dir2
中的文件。
以下是我的数据的一小部分样本
dir1 dir2 dir3
1.txt 1.txt 1.txt
2.txt 3.txt 3.txt
5.txt 4.txt 5.txt
6.txt 7.txt 8.txt
我想到的另一个问题是如何在一个命令中找到dir1
但不在dir2
或dir3
中的文件?
答案 0 :(得分:364)
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
仅打印文件名。
答案 1 :(得分:118)
答案 2 :(得分:48)
comm -23 <(ls dir1 |sort) <(ls dir2|sort)
此命令将为dir2中的dir1和 not 提供文件。
关于<( )
符号,您可以将其视为“流程替换”。
答案 3 :(得分:30)
进行此比较的一个好方法是将find
与md5sum
一起使用,然后使用diff
。
示例:
使用find
列出目录中的所有文件,然后计算每个文件的md5哈希并将其传输到文件:
find /dir1/ -type f -exec md5sum {} \; > dir1.txt
对另一个目录执行相同的过程:
find /dir2/ -type f -exec md5sum {} \; > dir2.txt
然后将结果两个文件与&#34; diff&#34;:
进行比较diff dir1.txt dir2.txt
当要比较的两个目录不在同一台机器上并且您需要确保两个目录中的文件相同时,此策略非常有用。
完成这项工作的另一个好方法是使用 git
git diff --no-index dir1/ dir2/
祝你好运!
答案 4 :(得分:15)
Meld(http://meldmerge.org/)在比较目录和文件中做得很好。
答案 5 :(得分:13)
vim的DirDiff插件是另一个非常有用的比较目录的工具。
vim -c "DirDiff dir1 dir2"
它不仅列出了目录中哪些文件不同,而且还允许您使用vimdiff检查/修改不同的文件。
答案 6 :(得分:10)
对所有回复都不满意,因为大多数回复工作得非常慢并且为大型目录产生不必要的长输出,我编写了自己的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
P.S。如果您需要比较文件大小和文件哈希值以进行潜在更改,我在此处发布了更新的脚本:https://gist.github.com/amakukha/f489cbde2afd32817f8e866cf4abe779
答案 7 :(得分:6)
另一个(大型目录可能更快)方法:
$ find dir1 | sed 's,^[^/]*/,,' | sort > dir1.txt && find dir2 | sed 's,^[^/]*/,,' | sort > dir2.txt
$ diff dir1.txt dir2.txt
sed
命令删除第一个目录组件thanks to Erik`s post)
答案 8 :(得分:5)
这有点晚了但可能对某人有所帮助。不确定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/'
答案 9 :(得分:5)
接受的答案还将列出两个目录中存在但具有不同内容的文件。要仅列出dir1中存在的文件,您可以使用:
diff -r dir1 dir2 | grep 'Only in' | grep dir1 | awk '{print $4}' > difference1.txt
说明:
答案 10 :(得分:4)
此答案通过添加-D
选项来优化@ Adail-Junior的建议之一,这在两个被比较的目录都不是git存储库时非常有用:
git diff -D --no-index dir1/ dir2/
如果使用-D
,则不会看到与/dev/null
的比较:
text
Binary files a/whatever and /dev/null differ
答案 11 :(得分:1)
使用DIFF命令比较2个目录的简化方法
运行完成后diff filename.1 filename.2&gt; filename.dat&gt;&gt;输入
打开filename.dat
你会看到: 仅在filename.1:filename.2中 仅在:directory_name:name_of_file1中 仅在:directory_Name:name_of_file2
答案 12 :(得分:1)
这是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|"
答案 13 :(得分:0)
kdiff3有一个很好的文件和目录的差异接口。
适用于Windows,Linux和macOS。
您可以通过多种方式安装它:
brew cask install kdiff3
答案 14 :(得分:0)
GNU grep
可以使用选项-v
进行反向搜索。这使得grep
报告不匹配的行。这样,您可以从dir2
中的文件列表中删除dir1
中的文件。
grep -v -F -x -f <(find dir2 -type f -printf '%P\n') <(find dir1 -type f -printf '%P\n')
选项-F -x
告诉grep
在整行中执行字符串搜索。