2つのディレクトリ間の差分を詳細に取得する

2つのディレクトリ間の差分を詳細に取得する

2つのディレクトリがあり、その差分をこの形式で出力する必要があります

例 :

DIR1 conatins :   file1
                  file2
                  file3
DIR2 contains :   file1
                  file4

出力(ファイル名のみ、ファイルの内容なし):file1 は変更または同じ、file2 は削除、file4 は追加

答え1

それは簡単です、人気のツールをチェックしてくださいdiffdiff -r dir1 dir2 編集:私はOPの質問を間違えて、情報だけを得ましたそれファイルは異なりますが、どうやって異なる場合は、-qオプションを使用する必要があります。 diff -r -q dir1 dir2

答え2

commまたはなどのツールがjoin2 つのソートされた入力セットを比較する方法を、 を使用してエミュレートしますbash

# Get lists of (base-)names from both directories.
files1=( dir1/* ); files1=( "${files1[@]##*/}" )
files2=( dir2/* ); files2=( "${files2[@]##*/}" )

# Loop over these sorted lists until one of them is empty.
while [[ ${#files1[@]} -gt 0 ]] && [[ ${#files2[@]} -gt 0 ]]; do
        name1=${files1[0]}
        name2=${files2[0]}

        if [[ $name1 == "$name2" ]]; then
                # Name exists in both directories.
                printf '%s is modified or same\n' "$name1"
                files1=( "${files1[@]:1}" )
                files2=( "${files2[@]:1}" )
        elif [[ $name1 < $name2 ]]; then
                # Name exists in only first directory.
                printf '%s is removed\n' "$name1"
                files1=( "${files1[@]:1}" )
        else
                # Name exists in only second directory.
                printf '%s is added\n' "$name2"
                files2=( "${files2[@]:1}" )
        fi
done

# Handle remaining names.
if [[ ${#files1[@]} -gt 0 ]]; then
        printf '%s is removed\n' "${files1[@]}"
fi
if [[ ${#files2[@]} -gt 0 ]]; then
        printf '%s is added\n' "${files2[@]}"
fi

各ディレクトリで見つかった名前を保持するために2 つの配列を使用しbash、これらの配列の 1 つが空になるまで反復処理を行います。

ループでは、各配列の最初の名前を互いに比較します。名前が同じ場合、ファイルは同じであるか、変更されている可能性があります (名前は両方の配列から削除されます)。

最初の配列の名前が 2 番目の配列の名前よりも前にソートされる場合 ( でテスト<)、最初の名前は 2 番目のディレクトリにありません。次に、最初の配列の最初の要素を削除します。

そうでない場合、2 番目の配列の名前は最初のディレクトリにありません。次に、2 番目の配列の最初の要素を削除します。

ループ後、配列の 1 つがまだ空でない可能性があるので、必要に応じてその配列から名前を出力します。

関連情報