2つのディレクトリがあり、その差分をこの形式で出力する必要があります
例 :
DIR1 conatins : file1
file2
file3
DIR2 contains : file1
file4
出力(ファイル名のみ、ファイルの内容なし):file1 は変更または同じ、file2 は削除、file4 は追加
答え1
それは簡単です、人気のツールをチェックしてくださいdiff
:
diff -r dir1 dir2
編集:私はOPの質問を間違えて、情報だけを得ましたそれファイルは異なりますが、どうやって異なる場合は、-q
オプションを使用する必要があります。
diff -r -q dir1 dir2
答え2
comm
またはなどのツールがjoin
2 つのソートされた入力セットを比較する方法を、 を使用してエミュレートします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 つがまだ空でない可能性があるので、必要に応じてその配列から名前を出力します。