diff只输出文件名

我正在寻找运行一个Linux的命令,将recursion比较两个目录, 输出不同的文件名。 这包括在一个目录中而不是在另一个目录中的任何内容,反之亦然,文本差异。

从diff手册页面:

-q仅报告文件是否有差异,而不是差异的细节。
-r比较目录时,recursion比较find的所有子目录。

示例命令:

 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 

你也可以使用rsync

 rsync -rv --size-only --dry-run /my/source/ /my/dest/ > diff.out 

如果你想得到只在一个目录中的文件列表,而不是它们的子目录,只有它们的文件名:

 diff -q /dir1 /dir2 | grep /dir1 | grep -E "^Only in*" | sed -n 's/[^:]*: //p' 

如果要recursion列出与完整path不同的所有文件和目录,请执行以下操作:

 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 {} 

在我的Linux系统上获取文件名

 diff -q /dir1 /dir2|cut -f2 -d' ' 

运行diff -qr old/ new/有一个主要缺点:它可能会遗漏新创build的目录中的文件。 例如,在下面的例子中, data/pages/playground/playground.txt不在diff -qr old/ new/的输出中,而目录data/pages/playground/是(在浏览器中searchplayground.txt来快速比较)。 我还在Unix和Linux Stack Exchange上发布了以下解决scheme,但是我也会在这里复制它:

要以编程方式创build新文件或修改文件的列表,我可以提出的最佳解决scheme是使用rsyncsortuniq

 (rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq 

让我来解释一下这个例子:我们想比较两个dokuwiki版本,看看哪些文件发生了变化,哪些是新创build的。

我们用wget获取焦油并将它们提取到old/ new/目录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的一种方式可能会丢失新创build的文件,因为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会丢失新创build的文件,而其他方式会错过已删除的文件,比较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这两种方式和sorting输出删除重复显示目录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 “recursion到目录”
  • -c还可以比较相同大小的文件,只能“跳过基于校验和,而不是时间和大小”,
  • -n “进行试运行,不做任何更改”,和
  • --out-format="%n"为“使用指定的格式输出更新”,这里是“%n”,仅用于文件名

rsync在两个方向上的输出(文件列表)将使用sort组合和sorting,然后通过使用uniq删除所有重复项来对此sorting的列表进行浓缩

 rsync -rvc --delete --size-only --dry-run source dir target dir