我在制作我想要制作的 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
您可以使用find
和awk
来解决这个问题。
具有以下布局:
$ 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