gnu diff は異なるフォルダー構造内のファイル名のみを再帰的に比較できますか?

gnu diff は異なるフォルダー構造内のファイル名のみを再帰的に比較できますか?

2 つのディレクトリを再帰的に比較し、差異のみを出力できることはわかっていますdiff -qr。ただし、これはツリー内のファイルの位置を比較しているようです (たとえば、/a/b/file01 != /b/c/file01)。

2 つの異なるツリーを比較して、ツリー内の位置に関係なく、一意のファイルのみを結果にしたいです。したがって、上記の例では、 はfile01一致と見なされます。 これは で可能ですか、それともネストされたループを実行してそれぞれを反復処理するdiff必要がありますか?find

答え1

私はいくつかの策略を使いますfind:

2 つのパスが /a と /b であるとします。

find /a/ /b/ -exec basename \{} \; | sort | uniq -u

つまり、これは「/a と /b 内のすべてのファイルを検索し、それらのベース名 (つまり、パスが削除された名前) を出力し、それらを並べ替えて、リスト内の一意の値を出力する」ということです。

これらのファイルがディレクトリ内のどこにあるかを見つけたい場合は、全体をループでラップして見つけることができます。

for i in `find /a/ /b/ -exec basename \{} \; | sort | uniq -u`; do find /a/ /b/ -name $i; done

答え2

ではそれは不可能だと思いますdiff。次のようなことを考えているのだと思います:

find tree1 -type f | while f=`line` ; do diff $f `find tree2 -type f -name "${f##*/}"`; done

tree2( の各ファイルで複数のインスタンスが許可されるか、インスタンスがまったく許可されないかtree1、および埋め込まれた空白が許可されるように、詳しく説明する必要があります。)

速度を上げるには、まずファイル リストを保存しますtree2

find tree2 -type f >tree2.list
find tree1 -type f | while f=`line` ; do diff $f `grep <tree2.list "/${f##*/}$"`; done

つまり、各ファイルに対して、ディレクトリ階層を検索するのではなく、1 つのファイルのみがスキャンされます。

関連情報