web-dev-qa-db-ja.com

Linuxの2つのディレクトリの違い

私は1つのディレクトリに存在するファイルを見つけようとしていますが、他のディレクトリにはありません、私はこのコマンドを使用しようとしました:

diff -q dir1 dir2

dir1にないがdir2にあるファイルとdir2にないdir1にあるファイルの両方を検出する上記のコマンドの問題、

ファイルをdir1で検索しようとしていますが、dir2のみでは検索できません。

ここに私のデータがどのように見えるかの小さなサンプルがあります

dir1    dir2    dir3
1.txt   1.txt   1.txt
2.txt   3.txt   3.txt
5.txt   4.txt   5.txt
6.txt   7.txt   8.txt

私のもう1つの質問は、単一のコマンドでdir1またはdir2でなくdir3でファイルを見つける方法です。

287
Error404
diff -r dir1 dir2 | grep dir1 | awk '{print $4}' > difference1.txt

説明:

  • diff -r dir1 dir2は、dir1にのみ存在するファイルとdir2にのみ存在するファイル、および存在する場合は両方のディレクトリに存在するファイルの変更も示します。

  • diff -r dir1 dir2 | grep dir1は、dir1にのみ存在するファイルを示します。

  • ファイル名のみを表示する場合はawk

361
asclepix

これは仕事をするはずです:

diff -rq dir1 dir2

オプションの説明(diff(1) manページ を介して):

  • -r - 見つかったサブディレクトリを再帰的に比較します。
  • -q - ファイルが異なるかどうかだけを出力します。
114
tokhi
comm -23 <(ls dir1 |sort) <(ls dir2|sort)

このコマンドは、dir1にあるファイルとdir2にあるnotのファイルを提供します。

<( )のサインについては、「プロセスの置き換え」としてグーグルできます。

48
plhn

この比較を行う良い方法は、findmd5sumと使用し、次にdiffを使用することです。

例:

findを使用してディレクトリ内のすべてのファイルを一覧表示し、各ファイルのmd5ハッシュを計算してファイルにパイプ処理します。

find /dir1/ -type f -exec md5sum {} \; > dir1.txt

別のディレクトリにも同じ手順を実行します。

find /dir2/ -type f -exec md5sum {} \; > dir2.txt

次に、結果の2つのファイルを "diff"と比較します。

diff dir1.txt dir2.txt

この方法は、比較する2つのディレクトリが同じマシンになく、ファイルが両方のディレクトリで等しいことを確認する必要がある場合に非常に役立ちます。

その仕事をするもう一つの良い方法は git を使うことです

git diff --no-index dir1/ dir2/

宜しくお願いします!

30
Adail Junior

Meld( http://meldmerge.org/ )はディレクトリとその中のファイルを比較するのに素晴らしい仕事をします。

Meld comparing directories

15
Catalin Hritcu

vimの DirDiff pluginはディレクトリを比較するためのもう一つの非常に便利なツールです。

vim -c "DirDiff dir1 dir2"

ディレクトリ間でどのファイルが異なるのかを一覧表示するだけでなく、異なるファイルをvimdiffで検査/変更することもできます。

13
drrossum

すべての回答に満足できません。ほとんどの回答は非常に遅く、大きなディレクトリに対して不必要に長い出力を生成するので、2つのフォルダを比較するために私自身のPythonスクリプトを書きました。

他の多くのソリューションとは異なり、ファイルの内容は比較されません。また、他のディレクトリにないサブディレクトリの中には入りません。そのため、出力は非常に簡潔で、スクリプトは速く機能します。

#!/usr/bin/env python3

import os, sys

def compare_dirs(d1: "old directory name", d2: "new directory name"):
    def print_local(a, msg):
        print('DIR ' if a[2] else 'FILE', a[1], msg)
    # ensure validity
    for d in [d1,d2]:
        if not os.path.isdir(d):
            raise ValueError("not a directory: " + d)
    # get relative path
    l1 = [(x,os.path.join(d1,x)) for x in os.listdir(d1)]
    l2 = [(x,os.path.join(d2,x)) for x in os.listdir(d2)]
    # determine type: directory or file?
    l1 = sorted([(x,y,os.path.isdir(y)) for x,y in l1])
    l2 = sorted([(x,y,os.path.isdir(y)) for x,y in l2])
    i1 = i2 = 0
    common_dirs = []
    while i1<len(l1) and i2<len(l2):
        if l1[i1][0] == l2[i2][0]:      # same name
            if l1[i1][2] == l2[i2][2]:  # same type
                if l1[i1][2]:           # remember this folder for recursion
                    common_dirs.append((l1[i1][1], l2[i2][1]))
            else:
                print_local(l1[i1],'type changed')
            i1 += 1
            i2 += 1
        Elif l1[i1][0]<l2[i2][0]:
            print_local(l1[i1],'removed')
            i1 += 1
        Elif l1[i1][0]>l2[i2][0]:
            print_local(l2[i2],'added')
            i2 += 1
    while i1<len(l1):
        print_local(l1[i1],'removed')
        i1 += 1
    while i2<len(l2):
        print_local(l2[i2],'added')
        i2 += 1
    # compare subfolders recursively
    for sd1,sd2 in common_dirs:
        compare_dirs(sd1, sd2)

if __name__=="__main__":
    compare_dirs(sys.argv[1], sys.argv[2])

使用例

user@laptop:~$ python3 compare_dirs.py dir1/ dir2/
DIR  dir1/out/flavor-domino removed
DIR  dir2/out/flavor-maxim2 added
DIR  dir1/target/vendor/flavor-domino removed
DIR  dir2/target/vendor/flavor-maxim2 added
FILE dir1/tmp/.kconfig-flavor_domino removed
FILE dir2/tmp/.kconfig-flavor_maxim2 added
DIR  dir2/tools/tools/LiveSuit_For_Linux64 added

あるいは、最初のディレクトリのファイルだけを見たい場合は、

user@laptop:~$ python3 compare_dirs.py dir2/ dir1/ | grep dir1
DIR  dir1/out/flavor-domino added
DIR  dir1/target/vendor/flavor-domino added
FILE dir1/tmp/.kconfig-flavor_domino added

P.Sあなたが潜在的な変化のためにファイルサイズとファイルハッシュを比較する必要があるならば、私はここで更新されたスクリプトを発表しました: https://Gist.github.com/amakukha/f489cbde2afd32817f8e866cf4abe779

10
Andriy Makukha

もう1つの方法(大規模ディレクトリの場合は高速)があります。

$ find dir1 | sed 's,^[^/]*/,,' | sort > dir1.txt && find dir2 | sed 's,^[^/]*/,,' | sort > dir2.txt
$ diff dir1.txt dir2.txt

sedコマンドは最初のディレクトリコンポーネントを削除します Erikの投稿のおかげで

6
jaltek

これは少し遅れますが、誰かに役立つかもしれません。 diffやrsyncがこのような裸のフォーマットでファイル名だけを吐き出しているかどうかわからない。私が以下で拡張したそのいい解決策を提供してくれたplhnに感謝します。

ファイル名だけが必要なので、必要なファイルをきれいな形式でコピーするのが簡単な場合は、findコマンドを使用できます。

comm -23 <(find dir1 | sed 's/dir1/\//'| sort) <(find dir2 | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'

これは、dir1とdir2の両方が同じ親フォルダーにあると想定しています。 sedは親フォルダを削除するだけなので、リンゴとリンゴを比較できます。最後のsedは単にdir1という名前を戻すだけです。

ファイルがほしい場合は、

comm -23 <(find dir1 -type f | sed 's/dir1/\//'| sort) <(find dir2 -type f | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'

ディレクトリについても同様です。

comm -23 <(find dir1 -type d | sed 's/dir1/\//'| sort) <(find dir2 -type d | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'
5
James

受け入れられた答えはまた両方のディレクトリに存在するが異なった内容を持っているファイルをリストするでしょう。 dir1に存在するファイルのみを一覧表示するには、次のようにします。

diff -r dir1 dir2 | grep 'Only in' | grep dir1 | awk '{print $4}' > difference1.txt

説明:

  • diff -r dir1 dir2:比較する
  • grep 'Only in': 'Only in'を含む行を取得する
  • grep dir1:dirを含む行を取得する
5
Aris

この回答は、-Dオプションを追加することで@ Adail-Juniorからの提案の1つを最適化します。これは、比較対象のディレクトリがどちらもgitリポジトリではない場合に役立ちます。

git diff -D --no-index dir1/ dir2/

-Dを使用した場合、/dev/nullとの比較は表示されません。text Binary files a/whatever and /dev/null differ

4
Mike Slinn

これは、2つのディレクトリを同期させるためのコマンドを出力するためのbashスクリプトです。

dir1=/tmp/path_to_dir1
dir2=/tmp/path_to_dir2
diff -rq $dir1 $dir2 | sed -e "s|Only in $dir2\(.*\): \(.*\)|cp -r $dir2\1/\2 $dir1\1|" |  sed -e "s|Only in $dir1\(.*\): \(.*\)|cp -r $dir1\1/\2 $dir2\1|" 
1
Ebru Yener

DIFFコマンドを使用して2つのディレクトリを比較する簡単な方法

diff filename.1 filename.2> filename.dat >>入力

実行完了後にfilename.datを開く

そして、あなたは見るでしょう:filename.1だけに:filename.2だけに:directory_name:name_of_file1だけに:directory_Name:name_of_file2

1
nerakk

GNU grepはオプション-vで検索を逆にすることができます。これによりgrepは行を報告しますが、一致しません。これによってdir2のファイルのリストからdir1のファイルを削除することができます。

grep -v -F -x -f <(find dir2 -type f -printf '%P\n') <(find dir1 -type f -printf '%P\n')

オプション-F -xは、行全体で文字列検索を実行するようにgrepに指示します。

0
ceving

kdiff3 にはファイルとディレクトリ用のNice diffインタフェースがあります。

Windows、Linux、およびmacOSで動作します。

インストール方法はいくつかあります。

0
ayakout