比较目录 1 中但不在目录 2 中的文件?

比较目录 1 中但不在目录 2 中的文件?

我在制作我想要制作的 bash 脚本时遇到了问题

我知道 ls 会列出目录中的文件,但我希望它列出目录 1 中但不在目录 2 中的目录,然后列出目录 2 中不在目录 1 中的文件。

在一次微弱的尝试中,我尝试了:

ls -al | diff directory1 directory2

很快我就意识到为什么它不起作用。任何人都可以帮助一个彻底的书呆子吗?

答案1

给定 bash,这可能是最简单的

$ comm <(ls -a dir1) <(ls -a dir2)

表达式<(command)运行命令通过管道并替换/dev/fd引用:

mress:10018 Z$ echo <(ls)
/dev/fd/11

因此,上面的命令ls -a在每个目录上运行,并将其输出作为文件参数提供给comm,最多输出 3 列,制表符缩进:仅第一个目录中的条目,两个目录中的条目,第二个目录中的条目。 (也就是说,如果它在两个文件中,则按一个制表符缩进,如果仅在第二个文件中,则按 2 个制表符缩进。)您还可以按数字抑制列: comm -1 foo bar仅显示两个文件中的行和第二个文件中的行,后者缩进为标签。 (最常用的方法是抑制除所需列之外的所有列: comm -13 foo bar仅显示公共行。)

鉴于您想要第一个目录中的内容,这意味着

$ comm -23 <(ls -a dir1) <(ls -a dir2)

如果您需要的不仅仅是它是否存在,请使用diff -r,它将输出公共文件的差异,并为仅在其中之一中找到的文件输出一行消息。

答案2

这是一个纯粹的脚本。这些是目录 a 和 b:

find a b
a
a/a
a/b
a/c
a/f
a/f/h
a/f/i
b
b/b
b/c
b/d
b/f
b/f/g
b/f/h

这是命令:

cd a
find ./ -exec test ! -e ../b/{} ";" -print 

输出:

./a
./f/i

交换 a 和 b 以获得 a 中但不在 b 中的文件。这 !是一个否定。 -e 测试 - 是否存在。在 prosa 中:“测试在 ../b 中 a 中找到的文件是否不存在”。

注意:您必须首先深入了解,才能获得不带“a”的名称。对于第二个比较,您必须 cd ../b

答案3

如果您更喜欢图形工具,请使用

xxdiff dir1 dir2 

您可能需要先安装它。类似的程序还有

gtkdiff
tkdiff

午夜指挥官有一个compare directories内置命令,如果您不使用子目录,它会很好用。

答案4

您可以使用findawk来解决这个问题。

具有以下布局:

$ mkdir a b a/1 b/1 b/2 a/3
$ touch a/f1 b/f1 a/f2 b/f3

第一部分:

$ find a b -mindepth 1 -maxdepth 1 -type d | \
    awk -F/ ' { if (!w[$1]) w[$1]=++i; if (w[$1]>1) b[$2]=1; else a[$2]=1; }
          END { for (x in a) if (!b[x]) print x }'
3

第二部分:

$ find b a -mindepth 1 -maxdepth 1 -type f | \
    awk -F/ ' { if (!w[$1]) w[$1]=++i; if (w[$1]>1) b[$2]=1; else a[$2]=1; }
          END { for (x in a) if (!b[x]) print x }'
f3

这与以下comm解决方案进行比较:

$ comm -23 <(ls a) <(ls b)    
3
f2
$ comm -13 <(ls a) <(ls b)
2
f3

并提出join解决方案:

$ join -v1 <(ls a) <(ls b)
3
f2
$ join -v2 <(ls a) <(ls b)
2
f3

相关内容