約300個のテキストファイルを含むフォルダがあります。各ファイルを個別に読み込み、重複エントリを削除するコマンドはありますか?ファイル名ではなく内容を意味します。
答え1
存在する場合は、fdupes
フォルダ内のすべての重複ファイルを一覧表示できます。
あなたは参照することができますこれこのコマンドの使用方法に関するオンラインチュートリアルですfdupes
。
テスト
という名前の3つのファイルを作成しました。ファイル1、ファイル2そしてファイル3そしてファイル1そしてファイル2まったく同じ内容です。
ここでコマンドを実行します。
fdupes -rdN .
そのうち(上記リンクから引用)、
- この
r
オプションを使用すると、fdupesはファイルを繰り返し検索します。 - この
d
オプションを使用すると、fdupesは重複エントリを削除します。 - この
N
オプションを一緒に使用すると、d
各重複セットの最初のファイルが保持され、ユーザーにメッセージを表示せずに他のファイルが削除されます。
上記のコマンドを実行した後ファイル1そしてファイル3私のフォルダにファイル2削除されました。
答え2
ピエール・オリビエ・バレッセ(Pierre Olivier Varese)の回答
スペースなどを含むファイル名を使用し-print0
てください。xargs -0
良い:
find . -type f -name "*.txt" -print0 |
xargs -0 md5sum |
awk '{print $2,$1}' |
sort -k 2 |
uniq --all-repeated=prepend -f 1 |
awk '/^$/ { I=1 }; /^./ { if (I==0) {print $1} I = 0; }' |
xargs echo
これを実行してください。合理的な結果が出たら、やり直すxargs rm --
のではなく使用してくださいxargs echo
。
答え3
fdupesが利用できない場合は、次のものも使用できます。
for first in *.txt
do
for second in *.txt
do
if diff $first $second >/dev/null 2>&1 && [ "$first" != "$second" ]
then
#echo $first and $second match. Deleting ${second}. # Optional, uncomment to use.
rm $second
fi
done
done
注:これは非常に非効率的です。 300個のファイルに対してdiffを90,000回実行します。かなり小さいファイルであればまだ高速ですが、大きなファイルであれば時間がかかることがあります。
答え4
2番目の答えとして、fdupesが利用できない場合のより効率的なアプローチは、md5を使用してハッシュを取得し、sortとuniqを使用してデュアルシェルループを使用せずに重複エントリを見つけることです。
次のようになります:(すべて1行で説明なし)
find . -type f -name '*.txt' // get recursively all .txt files
| xargs md5sum // compute the md5 sum
| awk '{print $2,$1}' // reverse the md5sum output
| sort -k 2 // sorts on the md5 hash
| uniq --all-repeated=prepend -f 1 // get groups of duplicate files
| awk '/^$/ { I=1 }; /^./ { if (I==0) {print $1} I = 0; }' // see below
| xargs rm // delete
発生したすべての.txtファイルを削除します。
(厳密に言うと、MD5の衝突は通常の状況では発生しないため無視されます。)
uniqとawkラインの説明:
Let's assume :
file1:This is a 1st content
file2:This is a 1st content
file3:This is a 2nd content
file4:This is a 3rd content
file5:This is a 1st content
file6:This is a 3rd content
ソート結果は次のとおりです。
file4 801620325e6bc5efa4333a9413811e23
file6 801620325e6bc5efa4333a9413811e23
file3 8f9722a09b4c6f0ddf867e268193ea1b
file1 a066d80d23803dffa9fbc1cdcd95e163
file2 a066d80d23803dffa9fbc1cdcd95e163
file5 a066d80d23803dffa9fbc1cdcd95e163
uniq --all-repeated=prepend -f 1
重複した項目のみを保持し、各ブロックの前に空白行を追加します。
(blank line)
file4 801620325e6bc5efa4333a9413811e23
file6 801620325e6bc5efa4333a9413811e23
(blank line)
file1 a066d80d23803dffa9fbc1cdcd95e163
file2 a066d80d23803dffa9fbc1cdcd95e163
file5 a066d80d23803dffa9fbc1cdcd95e163
その後、ミニ awk スクリプトは空行を無視し、空行に従わない行の最初のフィールドのみを印刷します。
(--> not printed: blank line)
(--> not printed: file4)
file6
(--> not printed: blank line)
(--> not printed: file1)
file2
file5
その後、xargs rmは残りのファイル(重複ファイルなど)をrmできます。