我正在寻找运行Linux命令,该命令将递归地比较两个目录并仅输出 不同的文件名。这包括一个目录中存在的任何内容,而不是另一个目录中的任何内容,反之亦然,以及文本差异。
答案 0 :(得分:319)
来自差异手册页:
-q
仅报告文件是否有所不同,而不是差异的详细信息。
-r
比较目录时,递归比较找到的所有子目录。
示例命令:
diff -qr dir1 dir2
示例输出(取决于区域设置):
$ ls dir1 dir2
dir1:
same-file different only-1
dir2:
same-file different only-2
$ diff -qr dir1 dir2
Files dir1/different and dir2/different differ
Only in dir1: only-1
Only in dir2: only-2
答案 1 :(得分:19)
您也可以使用rsync
rsync -rv --size-only --dry-run /my/source/ /my/dest/ > diff.out
答案 2 :(得分:11)
如果您想获取仅在一个目录而不是其子目录中的文件列表,并且只获取其文件名:
diff -q /dir1 /dir2 | grep /dir1 | grep -E "^Only in*" | sed -n 's/[^:]*: //p'
如果要递归列出与其完整路径不同的所有文件和目录:
diff -rq /dir1 /dir2 | grep -E "^Only in /dir1*" | sed -n 's/://p' | awk '{print $3"/"$4}'
这样,您可以对所有文件应用不同的命令。
例如,我可以删除dir1中的所有文件和目录,但不能删除dir2:
diff -rq /dir1 /dir2 | grep -E "^Only in /dir1*" | sed -n 's/://p' | awk '{print $3"/"$4}' xargs -I {} rm -r {}
答案 3 :(得分:8)
运行diff -qr old/ new/
的方法有一个主要缺点:它可能会丢失新创建的目录中的文件。例如。在下面的示例中,文件data/pages/playground/playground.txt
不在diff -qr old/ new/
的输出中,而目录data/pages/playground/
是(在浏览器中搜索 playground.txt 以快速比较)。我还发布了以下解决方案on Unix & Linux Stack Exchange,但我也将其复制到此处:
要以编程方式创建新文件或已修改文件的列表,我可以提出的最佳解决方案是使用 rsync ,排序和 uniq :
(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq
让我用这个例子来解释一下:我们想比较两个dokuwiki版本,看看哪些文件被更改了,哪些文件是新创建的。
我们使用wget获取tars并将其提取到目录old/
和new/
中:
wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29d.tgz
wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29.tgz
mkdir old && tar xzf dokuwiki-2014-09-29.tgz -C old --strip-components=1
mkdir new && tar xzf dokuwiki-2014-09-29d.tgz -C new --strip-components=1
以一种方式运行rsync可能会错过新创建的文件,因为rsync和diff的比较显示在此处:
rsync -rcn --out-format="%n" old/ new/
产生以下输出:
VERSION
doku.php
conf/mime.conf
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php
只在一个方向上运行rsync会错过新创建的文件而反过来会错过已删除的文件,比较diff的输出:
diff -qr old/ new/
产生以下输出:
Files old/VERSION and new/VERSION differ
Files old/conf/mime.conf and new/conf/mime.conf differ
Only in new/data/pages: playground
Files old/doku.php and new/doku.php differ
Files old/inc/auth.php and new/inc/auth.php differ
Files old/inc/lang/no/lang.php and new/inc/lang/no/lang.php differ
Files old/lib/plugins/acl/remote.php and new/lib/plugins/acl/remote.php differ
Files old/lib/plugins/authplain/auth.php and new/lib/plugins/authplain/auth.php differ
Files old/lib/plugins/usermanager/admin.php and new/lib/plugins/usermanager/admin.php differ
以两种方式运行rsync并对输出进行排序以删除重复项表明最初错过了目录data/pages/playground/
和文件data/pages/playground/playground.txt
:
(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq
产生以下输出:
VERSION
conf/mime.conf
data/pages/playground/
data/pages/playground/playground.txt
doku.php
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php
rsync
使用以下参数运行:
-r
to"进入目录",-c
还可以比较相同大小的文件,而且只有"基于校验和跳过,而不是mod-time&尺寸",-n
至"执行试运行而未进行任何更改"和--out-format="%n"
to"使用指定的FORMAT"输出更新,这是"%n"这里只提供文件名两个方向上rsync
的输出(文件列表)合并并使用sort
排序,然后通过删除uniq
答案 4 :(得分:7)
在我的linux系统上获取 文件名
diff -q /dir1 /dir2|cut -f2 -d' '
答案 5 :(得分:-4)
rsync -rvc --delete --size-only --dry-run source dir target dir