2011-06-02 117 views
166

我期待運行Linux命令,將遞歸地比較兩個目錄和輸出只有的有什麼不同的文件名。這包括出現在一個目錄中而不是另一個目錄中的任何內容,反之亦然,以及文本差異。DIFF只輸出文件名

回答

262

從DIFF手冊頁:文件只是否不同,的差別的細節

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

在我的Linux系統,以獲得只是文件名

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

除去所有重複縮合這並不對包含的paths工作步伐。 – michuelnik 2014-12-04 20:09:17

+4

我不會在我的linux系統上放置空格的文件名。 ;) – gerardw 2014-12-04 20:28:23

+4

我並不是故意將這個推定給你......; -p 就像暗示某人做了... – michuelnik 2014-12-05 16:34:48

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

您也可以使用rsync

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

「--size-only」將會丟失大小相同但內容不同的文件,例如_old/version.txt_ **「29a」** _new/version.txt_ **「29b」**。改爲使用:'rsync -ric --dry-run old/new /'其中「-i」參數允許直接通過rsync -ric --dry-run old/new/|獲取文件列表。 cut -d「」-f 2' – iolsmit 2015-03-24 17:15:16

+5

如果您只查找丟失的文件(特別是跨網絡共享),*因爲它不會比較內容,所以這很好。這幫助我找到了一些在遷移到新NAS時失敗的文件。 – OverZealous 2015-12-26 18:26:22

+1

確保在rsync的命令行中指定的路徑包含尾部斜線。無論如何,這將無法正常工作,rsync可能會列舉所有文件名! – 2017-11-18 00:37:21

7

運行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的焦油和他們提取到的目錄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的和差異的比較顯示在這裏:

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

+0

難道你只是反向運行它('diff new/old /')來查看哪些目錄被刪除? – 2017-04-05 08:24:15

+0

在上面的例子中用dokuwiki tars運行'diff -qr new/old /'會產生與'diff -qr old/new /'相同的輸出 - 即你看到該目錄是新的/丟失的,但不是其中的文件 – iolsmit 2017-04-05 15:08:16

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