Linux:ファイルを比較せずにディレクトリ構造を比較する


55

ファイル内のデータを実際に比較せずに2つのディレクトリ構造を比較するための最良かつ最も簡単な方法は何ですか?これはうまくいきます:

diff -qr dir1 dir2_

しかし、ファイルも比較しているため、本当に遅いです。これを行うためのdiffまたは別のシンプルなcliツールのスイッチはありますか?


「ディレクトリ構造」とは、ディレクトリパスだけですか、それともディレクトリファイルと非ディレクトリファイルの両方のパスですか?
直感

はい、フォルダファイル。
ジョナ

1
その場合は-type d、@ slartibartfastの回答からオプションを削除するか、私の回答を確認してください。
直観

回答:


36

次のコマンド(最初のディレクトリをdirectory1に、2番目のディレクトリをdirectory2に置き換えた場合)は、探していることを迅速に実行するはずです。

find directory1 -type d -printf "%P\n" | sort > file1
find directory2 -type d -printf "%P\n" | sort | diff - file1

基本的な原則は、ベースdirectoryNディレクトリを基準としたサブディレクトリパスを含むすべてのディレクトリを出力することです。

ディレクトリ名の一部にキャリッジリターンがあり、他のディレクトリ名にはない場合、これは落ちる可能性があります(奇妙な出力を生成します)。


1つのディレクトリに数千のファイルが含まれるフォルダが含まれている場合、それらはすべて個別に一覧表示されdiff -rqますが、ルートディレクトリが1つに存在することを示し、続行します。
クリスジェファーソン

(数年前)intuitedが指摘したように、OPsの質問に答えるために、-type dを削除して、ディレクトリと同様にファイルが比較で考慮されるようにする必要があります
user2746401

私は問題文を読むことを理解し、尊重します。それは当時の私の読書ではありませんでした。更新された質問に回答するために回答を編集することをお勧めしますか?一部の人々にとって役立つと思われる場合は、それを行うことは問題ありません。ソリューションとコメントをそのままにして、現在の方法をそのままにしておくことは大丈夫です。
Slartibartfast

34
vimdiff <(cd dir1; find . | sort) <(cd dir2; find . | sort)

共通のセクションが折りたたまれた状態で、2つのディレクトリ階層を並べて表示できます。


このソリューションはランダムに失敗します。vimが一時ファイル記述子を読み取る(または再読み取りする)とき、それはすでになくなっています。
デニルソンサマイア

23

私は通常rsyncこのタスクに使用します:

rsync -nav --delete DIR1/ DIR2

常に-naka--dry-run、オプションを使用する場合は注意が必要です。そうしないと、ディレクトリの同期(内容の変更)が行われます。

これは、ファイルの変更時間とサイズに基づいてファイルを比較します...それが本当に必要なものだと思いますか、少なくともそれを行う場合は気にしませんか?ファイルの内容の違いを無視するためにそれを必要とするのではなく、それをもっと速くしたいという感覚がありました。同じ名前の異なるファイルをリストしないようにする場合は、--ignore-existingオプションを追加するとそれができると思います。

また/、末尾にa を付けないDIR1と、ディレクトリ DIR1との内容が比較されることに注意してくださいDIR2

出力はやや冗長になりますが、どのファイル/ディレクトリが異なるかを示します。ファイル/ディレクトリに存在するものDIR2と存在しないもののDIR1前には、単語が付きdeletingます。

状況によっては、@ slartibartfastの答えがより適切かもしれませんが、-type dディレクトリ以外のファイルのリストを有効にするオプションを削除する必要があります。 rsync比較するファイル/ディレクトリの数が多い場合は高速になります。


素晴らしい答え。rsyncの出力では、deleting...テキストに気付くことは困難ですが、おそらく速度を維持しながらファイルを比較するための優れた方法の1つです。ここでのその他の回答は、OPの例のようにファイルの差分が必要ない場合は高速ですが、私はこれが本当に好きです。
ジョエルメロン14

これが私が望んでいたことです。ディレクトリツリーの大規模なペアにサイズの異なるファイルがいくつかあり、どのファイルを知りたいと思いました。これはわずか数秒でその目的を達成しました。
suprjami

読み取り専用アクセス権を持つユーザーで実行することをお勧めします。同様にsudo -u nobody rsync -nav --delete d1 d2「他人のためのフラグが読み取りを許可することを条件とします。
user1182474

このソリューションを実行すると、「ファイルリストの作成...完了\ n送信Xバイト受信YバイトZバイト/秒の合計サイズはAスピードアップがB」になりました(ここで、数値をXYZABに置き換えました)。それはすべてが同一だったことを意味しますか?より具体的なことは何も言及しなかったのですか?事前に感謝
スコットH

私自身の質問に答えるために、私はそれぞれに異なるファイルを追加することを実験しましたが、出力に記載されている特定のファイル/ディレクトリがすべて同じであることを意味しないようです。
スコットH

18

lsの回答に似ていますが、ツリーをインストールすると、次のことができます。

tree dir1 > out1
tree dir2 > out2
diff out1 out2

7
または、tmpfilesを避けるために、diff <( tree dir1 ) <( tree dir2 )
ジョエルメロン14

1
tree iフラグを付けてツリーを実行することをお勧めします。このフラグでは、ツリーの線(tree -i dir1など)は出力されません。ディレクトリ構造が1か所で異なる場合、一致する他のファイル|のツリー出力に含まれるシンボルの数が増減する可能性があり、ファイルパスが同じでもdiffはそれらの行をキャッチします。
askewchan

2
diff <(tree -i dir1)<(tree -i dir2)は間違いなく最良の答えです。質問がファイルの内容を読み取らないように明示的に言っているので、diffまたはrsyncを示唆するすべての回答をダウン票したいと思います。注:2つのパイプを使用する場合は、ブラケット間のスペースを慎重に使用する必要があります。例に従ってください。たとえば、バックアップ後の2つの20Gボリュームを比較すると、ツリーの回答には約5秒かかりました。他の人は20分以上かかりました。
ジェイソンモーガン

3

この問題の解決策を探していました。私が一番気に入った解決策は次のとおりです。

comm <(ls DIR1) <(ls DIR2)

1-DIR1のみのファイル、2-DIR2のみのファイル、3-DIR3のみのファイル詳細については、このブログ投稿をご覧ください


どこがDIR3指定されていますか?私が見るのはDIR1とだけDIR2です。
マイケルドースト

私は、出力された(私が言うことができるものから)それを試してみました、そして:だけで、すべてのファイルDIR1列1、のみ内のすべてのファイルDIR2列2、およびすべてのファイルの両方で共有して、カラム3。それは一種の有用ですが、列3を取り除き、違いだけを残す方法を知っていますか?私が持っている多くてソートするファイルのを、そのほとんどは同じです。同じものを見る必要はありません。
マイケルドースト

1
また、comm <(ls DIR1) <(ls DIR2)再帰的に機能しないことがわかりました。そのために使用しましたcomm <(ls -R1 DIR1) <(ls -R1 DIR2)ls -Rディレクトリを再帰的にクロールし、ls -1(これはLではなく1であることに注意してください)1行につき1つのファイル名のみを印刷します。ls
マイケルドースト

@マイケル:(comm -3参照man comm)。
ザズ14

2
ls > dir1.txt

ls > dir2.txt

次に、2つのリストを比較します。


OPはパスの階層を望んでいるようです。これにより、現在のディレクトリ内のすべてのファイルが比較されます。議論の余地はありますが、可能性としては、単にディレクトリが欲しいだけです。彼はファイルの内容ではなくファイル名が欲しいかもしれません。
直観

@intuited-あなたは正しい。誤解しています。
MDマーラ

2

これは最適なソリューションです

diff --brief -r dir1 dir2

--briefスイッチは、ファイルの違いのみを報告し、違いの詳細は報告しません。


1
OPにはすでに-q質問があり--briefます。これはのエイリアスです。この回答は新しい情報を提供しません。
マイケルドースト

1
OPはファイルの内容を比較したくない。But it's really slow because it's comparing files too.
ジョエルメロン14

1

「diff -qr」を使用してさまざまなファイルを取得し、grepを使用してファイル比較を除外して、いずれかのディレクトリにあるファイル名のみを取得します。

diff -qr dir1 dir2 | grep -v "Files.*differ" 

1

これは、一致すると予想されるツリー内の欠落ファイルを見つけるという特定のニーズに対応しました。

diff <( cd dir1; find * |sort ) <(cd dir2; find * | sort)

-3

rsyncのみがユーザーフルだと思います。どうして?

diffは、ファイルとディレクトリを保持する構造にのみ役立ちます。Diffは、シンボリックリンクを使用するときに適切な終了コードを提供しません。その場合、srcとdstが同一(時間、サイズ、名前、タイムスタンプ、ポインティングソフトリンクなど)であっても、diffは2つの終了コードを返すことができます。

dir、srcとdstのディレクトリの内容が同一であっても、ファイルシステムはファイルの順序を保証しません。たぶん、あなたはそれをソートすることによってls出力をフィルタリングする必要があります。ただし、純粋なlsはノード名のみを表示します。

ノードタイプのdiff、cmp、test -Xを含むスクリプトは便利かもしれませんが、多くのtest / cmpの実行によって生じる過負荷について覚えておいてください。スクリプトは非常に遅くなります。

いつものように、「dirs is / is n't同一」という簡単な情報を取得したい場合は、-n(dry)オプションを指定してrsyncを使用する必要があります。違いを見つけたい場合は、diffコマンドを使用します。


マイナスの理由を知りたいのですが?
ズニック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.