Temukan file duplikat

91

Apakah mungkin untuk menemukan file duplikat di disk saya yang sedikit identik tetapi memiliki nama file yang berbeda?

siswa
sumber
3
Perhatikan bahwa setiap metode yang mungkin untuk melakukan ini harus selalu membandingkan setiap file pada sistem Anda dengan setiap file lainnya . Jadi ini akan memakan waktu lama , bahkan saat mengambil jalan pintas.
Shadur
4
@ Safar jika ada yang ok dengan checksum, itu bermuara untuk membandingkan hanya hash - yang pada kebanyakan sistem adalah urutan 10 ^ (5 + -1) biasanya <entri 64-byte. Tentu saja, Anda harus membaca data paling tidak satu kali. :)
peterph
15
@ Safur Itu tidak benar. Anda dapat mengurangi waktu dengan memeriksa untuk pencocokan st_sizes, menghilangkan mereka dengan hanya satu yang sama, dan kemudian hanya menghitung md5sums untuk pencocokan st_sizes.
Chris Down
6
@ Safad bahkan sebuah pendekatan yang sangat konyol yang melarang operasi hash apa pun dapat melakukan ini di Θ (n log n) membandingkan — bukan Θ (n²) —menggunakan salah satu dari beberapa macam algoritma (berdasarkan konten file).
derobert
1
@ ChrisDown Ya, pencocokan ukuran akan menjadi salah satu cara pintas yang ada dalam pikiran saya.
Shadur

Jawaban:

104

fdupesdapat melakukan ini. Dari man fdupes:

Mencari jalur yang diberikan untuk file duplikat. File tersebut ditemukan dengan membandingkan ukuran file dan tanda tangan MD5, diikuti oleh perbandingan byte-by-byte.

Di Debian atau Ubuntu, Anda dapat menginstalnya dengan apt-get install fdupes. Di Fedora / Red Hat / CentOS, Anda dapat menginstalnya dengan yum install fdupes. Di Arch Linux, Anda dapat menggunakan pacman -S fdupes, dan di Gentoo emerge fdupes,.

Untuk menjalankan pemeriksaan menurun dari root sistem file Anda, yang kemungkinan akan memakan banyak waktu dan memori, gunakan sesuatu seperti fdupes -r /.

Seperti yang ditanyakan dalam komentar, Anda bisa mendapatkan duplikat terbesar dengan melakukan hal berikut:

fdupes -r . | {
    while IFS= read -r file; do
        [[ $file ]] && du "$file"
    done
} | sort -n

Ini akan rusak jika nama file Anda mengandung baris baru.

Chris Down
sumber
Terima kasih. Bagaimana saya bisa memfilter korban penipuan terbesar? Bagaimana saya bisa membuat ukuran yang dapat dibaca manusia?
siswa
@student: gunakan sesuatu di sepanjang baris (pastikan fdup hanya mengeluarkan nama file tanpa informasi tambahan, atau memotong atau memperkecil hanya untuk menyimpannya): fdupes ....... | xargs ls -alhd | egrep 'M |G 'untuk menyimpan file dalam format yang dapat dibaca Manusia dan hanya file dengan ukuran dalam Megabita atau Gigabita. Ubah perintah agar sesuai dengan hasil nyata.
Olivier Dulac
2
@OlivierDulac Anda seharusnya tidak menguraikan ls . Biasanya itu lebih buruk daripada use case Anda, tetapi bahkan dalam use case Anda, Anda berisiko positif palsu.
Chris Down
@student - Setelah Anda memiliki nama file, dupiped untuk sortmemberi tahu Anda.
Chris Down
@ ChrisDown: memang benar itu kebiasaan buruk, dan bisa memberikan hasil positif palsu. Tetapi dalam hal itu (penggunaan interaktif, dan hanya untuk tampilan, tidak ada "rm" atau apapun yang secara langsung bergantung padanya) tidak masalah dan cepat ^^. Saya suka halaman-halaman yang Anda tautkan, btw (telah membacanya sejak beberapa bulan, dan penuh dengan banyak info berguna)
Olivier Dulac
27

Alat bagus lainnya adalah fslint:

fslint adalah toolset untuk menemukan berbagai masalah dengan sistem file, termasuk file duplikat dan nama file yang bermasalah, dll.

Alat baris perintah terpisah tersedia sebagai tambahan untuk GUI dan untuk mengaksesnya, seseorang dapat mengubah, atau menambah $ PATH direktori / usr / share / fslint / fslint pada instalasi standar. Masing-masing perintah dalam direktori tersebut memiliki opsi --help yang selanjutnya merinci parameternya.

   findup - find DUPlicate files

Pada sistem berbasis debian, Anda dapat menginstalnya dengan:

sudo apt-get install fslint

Anda juga dapat melakukan ini secara manual jika Anda tidak ingin atau tidak dapat menginstal alat pihak ketiga. Cara sebagian besar program tersebut bekerja adalah dengan menghitung checksum file . File dengan md5sum yang sama hampir pasti berisi data yang persis sama. Jadi, Anda bisa melakukan sesuatu seperti ini:

find / -type f -exec md5sum {} \; > md5sums
gawk '{print $1}' md5sums | sort | uniq -d > dupes
while read d; do echo "---"; grep $d md5sums | cut -d ' ' -f 2-; done < dupes 

Output sampel (nama file dalam contoh ini sama, tetapi juga akan berfungsi ketika mereka berbeda):

$ while read d; do echo "---"; grep $d md5sums | cut -d ' ' -f 2-; done < dupes 
---
 /usr/src/linux-headers-3.2.0-3-common/include/linux/if_bonding.h
 /usr/src/linux-headers-3.2.0-4-common/include/linux/if_bonding.h
---
 /usr/src/linux-headers-3.2.0-3-common/include/linux/route.h
 /usr/src/linux-headers-3.2.0-4-common/include/linux/route.h
---
 /usr/src/linux-headers-3.2.0-3-common/include/drm/Kbuild
 /usr/src/linux-headers-3.2.0-4-common/include/drm/Kbuild
---

Ini akan jauh lebih lambat daripada alat khusus yang telah disebutkan, tetapi itu akan berhasil.

terdon
sumber
4
Akan jauh lebih cepat untuk menemukan file dengan ukuran yang sama dengan file lain yang digunakan st_size, menghilangkan file yang hanya memiliki satu file dengan ukuran ini, dan kemudian menghitung md5sums hanya antara file dengan yang sama st_size.
Chris Down
@ ChrisDown ya, hanya ingin tetap sederhana. Apa yang Anda sarankan tentu saja akan mempercepat banyak hal. Itu sebabnya saya memiliki disclaimer tentang hal itu menjadi lambat pada akhir jawaban saya.
terdon
Itu bisa dijalankan di macOS, tetapi Anda harus mengganti md5sum {}dengan md5 -q {}dan gawk '{print $1}'dengancat
Finesse
8

Jawaban singkat: ya.

Versi yang lebih panjang: lihat entri wikipedia fdupes , ini daftar yang cukup bagus dari solusi yang sudah jadi. Tentu saja Anda dapat menulis sendiri, itu tidak bahwa sulit - program hashing seperti diff, sha*sum, find, sortdan uniqharus melakukan pekerjaan. Anda bahkan dapat meletakkannya di satu baris, dan itu masih bisa dimengerti.

peterph
sumber
6

Jika Anda yakin fungsi hash (di sini MD5) bebas tabrakan di domain Anda:

find $target -type f -exec md5sum '{}' + | sort | uniq --all-repeated --check-chars=32 \
 | cut --characters=35-

Ingin nama file yang identik dikelompokkan? Tulis skrip sederhana not_uniq.shuntuk memformat output:

#!/bin/bash

last_checksum=0
while read line; do
    checksum=${line:0:32}
    filename=${line:34}
    if [ $checksum == $last_checksum ]; then
        if [ ${last_filename:-0} != '0' ]; then
            echo $last_filename
            unset last_filename
        fi
        echo $filename
    else
        if [ ${last_filename:-0} == '0' ]; then
            echo "======="
        fi
        last_filename=$filename
    fi

    last_checksum=$checksum
done

Kemudian ubah findperintah untuk menggunakan skrip Anda:

chmod +x not_uniq.sh
find $target -type f -exec md5sum '{}' + | sort | not_uniq.sh

Ini ide dasar. Mungkin Anda harus berubah findjika nama file Anda mengandung beberapa karakter. (mis. ruang)

xin
sumber
6

Saya berpikir untuk menambahkan garpu fdupes yang disempurnakan, jdupes , yang menjanjikan lebih cepat dan lebih kaya fitur daripada fdupes (mis. Filter ukuran):

jdupes . -rS -X size-:50m > myjdups.txt

Ini akan secara rekursif menemukan file duplikat lebih besar dari 50MB di direktori saat ini dan menampilkan daftar yang dihasilkan di myjdups.txt.

Catatan, output tidak diurutkan berdasarkan ukuran dan karena tampaknya tidak dibangun, saya telah mengadaptasi jawaban @Chris_Down di atas untuk mencapai ini:

jdupes -r . -X size-:50m | {
    while IFS= read -r file; do
        [[ $file ]] && du "$file"
    done
} | sort -n > myjdups_sorted.txt
Sebastian Müller
sumber
Catatan: versi terbaru dari jdupes mendukung file yang cocok dengan hanya sebagian hash daripada menunggu hash semuanya. Sangat berguna. (Anda harus mengkloning arsip git untuk mendapatkannya.) Berikut adalah opsi yang saya gunakan sekarang: jdupes -r -T -T --exclude = size-: 50m --nohidden
SurpriseDog
2

Wikipedia memiliki artikel ( http://en.wikipedia.org/wiki/List_of_duplicate_file_finders ), dengan daftar perangkat lunak sumber terbuka yang tersedia untuk tugas ini, tetapi sekarang telah dihapus .

Saya akan menambahkan bahwa versi GUI dari fslint sangat menarik, memungkinkan untuk menggunakan mask untuk memilih file mana yang akan dihapus. Sangat berguna untuk membersihkan foto yang digandakan.

Di Linux Anda dapat menggunakan:

- FSLint: http://www.pixelbeat.org/fslint/

- FDupes: https://en.wikipedia.org/wiki/Fdupes

- DupeGuru: https://www.hardcoded.net/dupeguru/

2 pekerjaan terakhir pada banyak sistem (windows, mac dan linux) Saya belum memeriksa FSLint

MordicusEtCubitus
sumber
5
Lebih baik memberikan informasi aktual di sini dan bukan hanya tautan, tautannya mungkin berubah dan kemudian jawabannya tidak ada nilainya
Anthon
2
Halaman Wikipedia kosong.
ihor_dvoretskyi
ya, sudah dibersihkan, sayang sekali ...
MordicusEtCubitus
Saya telah mengeditnya dengan 3 alat ini
MordicusEtCubitus
0

Inilah pendapat saya:

find -type f -size +3M -print0 | while IFS= read -r -d '' i; do
  echo -n '.'
  if grep -q "$i" md5-partial.txt; then echo -e "\n$i  ---- Already counted, skipping."; continue; fi
  MD5=`dd bs=1M count=1 if="$i" status=noxfer | md5sum`
  MD5=`echo $MD5 | cut -d' ' -f1`
  if grep "$MD5" md5-partial.txt; then echo "\n$i  ----   Possible duplicate"; fi
  echo $MD5 $i >> md5-partial.txt
done

Ini berbeda karena hanya memiliki hash hingga 1 MB file.
Ini memiliki beberapa masalah / fitur:

  • Mungkin ada perbedaan setelah 1 MB pertama sehingga hasilnya lebih cocok untuk diperiksa. Saya mungkin memperbaikinya nanti.
  • Memeriksa berdasarkan ukuran file terlebih dahulu dapat mempercepat ini.
  • Hanya membutuhkan file yang lebih besar dari 3 MB.

Saya menggunakannya untuk membandingkan klip video jadi ini sudah cukup bagi saya.

Ondra Žižka
sumber