ディレクトリにx個のファイルがあり(x = 100より大きい)、このファイルの違いを比較したいとします。これをどのように実行できますか?私はUbuntu 18.04マシンを実行しています。議論のために、ディレクトリが/home/user1/music_list/で、そのディレクトリにあるファイルの1つが/home/user1/music_list/jazz1.txtであるとします。
答え1
これは実際にはファイルが本質的に同じかどうかによって異なります。何千もの比較を提示することも、「参照バージョン」や一連の漸進的な修正を識別できない場合は完全に混乱します。
一度は、信頼性の問題がある排出メカニズムの問題を解決するように求められたことがあります。電力網サイトの各階層には、16,000個のイメージファイル、つまり250万個のファイルを持つ160個のサーバーがあります。
基本的に最も人気のあるバージョンに投票してもらいました。各サーバーには独自のファイルチェックサムがあり、チェックサム、日付、サイズ、名前のリストを私に送信します。チェックサムにグループ化して計算します。コレクション全体で100%一貫性のあるすべてのファイルが利用可能です。ケースの80%以上に一致するものには、更新がないサーバーが表示されます。 20%未満の場合、削除に失敗したか悪意のあるテストファイルです。 20~80%の範囲に入る人はほとんどいません。
私のユースケースでは、間違った名前またはパスで別のサーバーにアップロードされたイメージファイルを検出するのも簡単でした。
このアプローチは問題を解決できないかもしれませんが、必要な詳細比較の数を大幅に減らします。
答え2
このスクリプトを試してみてください。
diff
希望の出力に応じて、またはコマンドを追加しました。comm
for i in /home/user1/music_list/*.txt; do
index_file="$i"
echo "$(tput setaf 1)Comparing "$i" $(tput sgr 0)"
for n in /home/user1/music_list/*.txt; do
next_file="$n"
echo "$(tput setaf 5)With "$n" $(tput sgr 0)"
#comm -3 <(sort "$index_file") <(sort "$next_file")
diff -s <(sort "$index_file") <(sort "$next_file")
shift
done
done
に出力comm
Comparing z.txt
With z1.txt
With z2.txt
1
2
With z3.txt
1
22
With z4.txt
1
222
comm
名前が同じ場合、名前は印刷されますが出力されません。z1.txt
に出力diff
Comparing z.txt
With z1.txt
Files /dev/fd/63 and /dev/fd/62 are identical
With z2.txt
1c1
< 1
---
> 2
With z3.txt
1c1
< 1
---
> 22
With z4.txt
1c1
< 1
---
> 222
答え3
/some/dir
すべての一般ファイルを1対1で(再帰的に)比較するには、次のようにしますzsh
。
function {
local fileA fileB
for fileA do
shift
for fileB do
diff -su $fileA $fileB
done
done
} /some/dir/**/*(ND.)
これは、同じ形式とコンテキストの違い-u
とファイルが同じ場合の-s
(非標準)レポートを示しています。
ただし、ファイルが100を超える場合は、数千回の1対1の比較が必要です。
GNUを使用すると、オプションをdiff
追加して匿名関数の出力を渡すことで、その出力をより受け入れ可能にすることができます。--color=always
diff
less -R
bash
代わりにと同じですzsh
が、バージョン4.4以降(用)とユーティリティreadarray -d
(および拡張用)のGNU実装(または互換性)を想定しています。find
sort
-print0
-z
(
readarray -td '' files < <(
find /some/dir/ -type f -print0 | sort -z)
set -- "${files[@]}"
for fileA do
shift
for fileB do
diff -su "$fileA" "$fileB"
done
done
)
重複する項目が多い場合は、まずどのファイルが同じかを確認してから、同じファイル内の各グループから1つのファイルのみを選択して、他のグループの1つのファイルと比較することで、比較回数を減らすことができます。
そしてzsh
:
typeset -A set
files=(/some/dir/**/*(ND.))
for file in $files; do
sum=$(sha1sum < $file) || continue
# store the list of files having a given checksum NUL delimited
# in an associative array
set[$sum]+=$file$'\0'
done
sums=(${(k)set})
for sum1 in $sums; do
shift 1 sums
files1=(${(0)set[$sum1]}) # split on NUL
(( $#files < 2 )) || print -r All of ${(j[, ])files1} are identical
for sum2 in $sums; do
files2=(${(0)set[$sum2]})
diff -u $files1[1] $files2[1]
done
done
(検証されていません)。
答え4
/home/user1/music_list/ディレクトリにあるファイルが1つだけ固有であることを私に伝えることで、上記の問題が改善されたとします。唯一のファイルが何であるかを見つけるには、次の答えを検討し、どう思うか教えてください。
$diff -r --from-file=/home/user1/music_list/jazz1.txt /home/user1/music_list/
アイデアは、./jazz.txtディレクトリ内のファイルを同じディレクトリ内の他のすべてのファイルと比較して、どのファイルがjazz.txtと異なるかを確認できることです。