如何比较并仅显示不同文件的文件名?

问题描述 投票:0回答:7

我希望运行一个 Linux 命令,该命令将递归比较两个目录并仅输出不同的文件名。这包括一个目录中存在而不是另一个目录中存在的任何内容,反之亦然,以及文本差异。

linux command-line diff
7个回答
485
投票

-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



46
投票

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



18
投票

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



13
投票
diff -qr old/ new/

的方法有一个主要缺点:它可能会丢失新创建的目录中的文件。例如。在下面的示例中,文件

data/pages/playground/playground.txt
不在
diff -qr old/ new/
的输出中,而目录
data/pages/playground/
位于(在浏览器中搜索
playground.txt
进行快速比较)。我还在 Unix & Linux Stack Exchange 上发布了以下解决方案,但我也会将其复制到此处: 要以编程方式创建新文件或修改文件的列表,我能想到的最佳解决方案是使用 rsync

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

让我用这个例子来解释一下:我们想要比较两个 dokuwiki 版本,看看哪些文件被更改了,哪些文件是新创建的。

我们使用 wget 获取 tar 并将它们解压到目录

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
    到“递归到目录”,
  • -c
  • 还可以比较相同大小的文件,并且仅“根据校验和跳过,而不是修改时间和大小”,
  • -n
  • “执行试运行而不进行任何更改”,并且
  • --out-format="%n"
  • “使用指定的格式输出更新”,这里的“%n”仅用于文件名
  • 
    
  • rsync
在两个方向上的输出(文件列表)使用

sort

进行组合和排序,然后通过使用
uniq
删除所有重复项来压缩此排序列表
    

在我的 Linux 系统上获取

12
投票
文件名

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

我有一个目录。

3
投票
$ tree dir1 dir1 ├── a │   └── 1.txt ├── b │   └── 2.txt └── c ├── 3.txt ├── 4.txt └── d └── 5.txt 4 directories, 5 files

我还有另一个目录。
$ tree dir2
dir2
├── a
│   └── 1.txt
├── b
└── c
    ├── 3.txt
    ├── 5.txt
    └── d
        └── 5.txt

4 directories, 4 files

我可以区分两个目录。
$ diff <(cd dir1; find . -type f | sort) <(cd dir2; find . -type f| sort)
--- /dev/fd/11  2022-01-21 20:27:15.000000000 +0900
+++ /dev/fd/12  2022-01-21 20:27:15.000000000 +0900
@@ -1,5 +1,4 @@
 ./a/1.txt
-./b/2.txt
 ./c/3.txt
-./c/4.txt
+./c/5.txt
 ./c/d/5.txt

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

-5
投票

© www.soinside.com 2019 - 2024. All rights reserved.