ファイル名のみを出力するdiff


243

2つのディレクトリを再帰的に比較し、相違点のファイル名のみを出力するLinuxコマンドを実行したいと考えています。これには、1つのディレクトリに存在し、他のディレクトリには存在しない、またはその逆のあらゆるものが含まれ、テキストの違いも含まれます。

回答:


374

diffのmanページから:

-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

ありがとうdiff-CentOS 7のmanページでは-q、「ファイルが異なる場合にのみレポートする」と記述されていますが、これはあなたが書いたものほど明確ではありません。

2
これはファイルの実際のコンテンツを比較しますが、これはたいていの場合望まれますが、rsyncの回答では、ファイル名とサイズのみを確認し、コンテンツは確認しないという選択肢があります。それは時々望ましいです。
steveb

macOSでも動作します。
Marius Soutier

また、-x PATTERN特定のサブディレクトリを除外するコマンドに含めることができます。たとえば、diff -qr repo1 repo2 -x ".git" 2つのディレクトリを比較しますが、「。git」が含まれるファイルパスを除外します。
ViFI

27

rsyncを使用することもできます

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

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

6
これは、内容を比較しないため、見つからないファイル(特にネットワーク共有全体)のみを検索する場合に最適です。これは、新しいNASに移行するときに失敗したいくつかのファイルを見つけるのに役立ちました。
OverZealous

4
rsyncのコマンドラインで指定されたパスの末尾のスラッシュを必ず含めてください。それらがなければ、これは正しく動作せず、rsyncはおそらくすべてのファイル名を列挙するだけです!
Vladimir Panteleev 2017年

2
内容を確認しないことについてのコメントについて。これは、少なくとも最初のパスとしては望ましい場合があります。
steveb

13

1つのディレクトリのみにあり、サブディレクトリではなくファイル名のみのファイルのリストを取得する場合:

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

9

私のLinuxシステムでファイル名だけを取得する

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

7
Linuxシステムではスペースを含むファイル名を使用しません。;)
gerardw 14

6
私はこれをあなたに告げるつもりはありませんでした... ;-p誰かがそうする誰かへのヒントと同じように...
michuelnik

私にはうまくいきません。私のディレクトリ構造は以下のようなものですaudit-0.0.234/audit-data-warehouse-0.0.234/ audit-0.0.235/audit-data-warehouse-0.0.235/
Alex Raj Kaliamoorthy

diff -qrN /dir1 /dir2 | cut -f2 -d' '私にとってはうまくいきます!
Francesco

9

実行のアプローチにdiff -qr old/ new/は、1つの大きな欠点があります。新しく作成されたディレクトリ内のファイルを見逃す可能性があります。たとえば、以下の例では、ファイルdata/pages/playground/playground.txtはの出力に含まれていません diff -qr old/ new/が、ディレクトリdata/pages/playground/は(ブラウザでplayground.txtを検索してすばやく比較できます)。また、次のソリューションをUnix&Linux Stack Exchangeに投稿しましたが、ここにもコピーします。

プログラムで新しいファイルまたは変更されたファイルのリストを作成するには、rsyncsortuniqを使用するのが最善の方法です。

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

この例で説明しましょう。2つの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とdiffの比較がここに示すように、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の出力を比較します。

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 同じサイズのファイルのみを比較し、「mod-timeとsizeではなく、チェックサムに基づいてスキップする」
  • -n 「変更を加えずに試運転を行う」、および
  • --out-format="%n" 「指定されたFORMATを使用して更新を出力する」。これは、ここではファイル名のみの「%n」です

の出力(ファイルのリスト)はrsync、を使用して結合およびソートsortされます。次に、このソートされたリストは、uniq


逆方向(diff new/ old/)に実行して、削除されたディレクトリを確認できませんか?
ジャック

diff -qr new/ old/上記の例でdokuwiki tarを使用して実行すると、同じ出力が生成されdiff -qr old/ new/ます。つまり、ディレクトリは新規/欠落しているが、その中のファイルはないことが
わかり

-4
rsync -rvc --delete --size-only --dry-run source dir target dir
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.