Wie entferne ich doppelte Dateien in einem Verzeichnis?

Wie entferne ich doppelte Dateien in einem Verzeichnis?

Ich habe viele Bilder in ein Verzeichnis heruntergeladen.
Der Downloader hat bereits vorhandene Dateien umbenannt.
Einige der Dateien habe ich auch manuell umbenannt.

a.jpg
b.jpg
b(2).jpg
hello.jpg      <-- manually renamed `b(3).jpg`
c.jpg
c(2).jpg
world.jpg      <-- manually renamed `d.jpg`
d(2).jpg
d(3).jpg

Wie entferne ich Duplikate? Das Ergebnis sollte sein:

a.jpg
b.jpg
c.jpg
world.jpg

Hinweis: Der Name ist egal. Ich möchte nur eindeutige Dateien.

Antwort1

bash 4.x

#!/bin/bash
declare -A arr
shopt -s globstar

for file in **; do
  [[ -f "$file" ]] || continue
   
  read cksm _ < <(md5sum "$file")
  if ((arr[$cksm]++)); then 
    echo "rm $file"
  fi
done

Dies ist sowohl rekursiv als auch für jeden Dateinamen geeignet. Der Nachteil ist, dass Version 4.x erforderlich ist, um assoziative Arrays und rekursive Suche verwenden zu können. Entfernen Sie dies, echowenn Sie mit den Ergebnissen zufrieden sind.

gawk-Version

gawk '
  {
    cmd="md5sum " q FILENAME q
    cmd | getline cksm
    close(cmd)
    sub(/ .*$/,"",cksm)
    if(a[cksm]++){
      cmd="echo rm " q FILENAME q
      system(cmd)
      close(cmd)
    }
    nextfile
  }' q='"' *

Beachten Sie, dass dies bei Dateien, deren Namen Anführungszeichen enthalten, immer noch nicht funktioniert. Mit gibt es keine wirkliche Möglichkeit, dies zu umgehen awk. Entfernen Sie das echo, wenn Ihnen das Ergebnis gefällt.

Antwort2

Abonnierenist das Tool Ihrer Wahl. So finden Sie alle doppelten Dateien (nach Inhalt, nicht nach Namen) im aktuellen Verzeichnis:

fdupes -r .

So bestätigen Sie das Löschen doppelter Dateien manuell:

fdupes -r -d .

Um alle Kopien bis auf die erste jeder duplizierten Datei automatisch zu löschen (Seien Sie gewarnt, diese Warnung löscht tatsächlich Dateien, wie gewünscht):

fdupes -r -f . | grep -v '^$' | xargs rm -v

Ich empfehle, Dateien vor dem Löschen manuell zu überprüfen:

fdupes -rf . | grep -v '^$' > files
... # check files
xargs -a files rm -v

Antwort3

Ich empfehleAbonnieren.

Fclones ist ein moderner Sucher und Entferner für doppelte Dateien, der in Rust geschrieben ist und auf den meisten Linux-Distributionen und macOS verfügbar ist.

Bemerkenswerte Funktionen:

  • unterstützt Leerzeichen, Nicht-ASCII-Zeichen und Steuerzeichen in Dateipfaden
  • ermöglicht die Suche in mehreren Verzeichnisbäumen
  • respektiert .gitignore-Dateien
  • sicher: ermöglicht die manuelle Überprüfung der Liste der Duplikate, bevor eine Aktion an ihnen durchgeführt wird
  • bietet zahlreiche Optionen zum Filtern/Auswählen von Dateien zum Entfernen oder Beibehalten
  • sehr schnell

Um im aktuellen Verzeichnis nach Duplikaten zu suchen, führen Sie einfach Folgendes aus:

fclones group . >dupes.txt

Anschließend können Sie die Datei überprüfen dupes.txt, um zu prüfen, ob die richtigen Duplikate gefunden wurden (Sie können die Liste auch nach Belieben ändern).

Entfernen/verknüpfen/verschieben Sie abschließend die doppelten Dateien mit einer der folgenden Methoden:

fclones remove <dupes.txt
fclones link <dupes.txt
fclones move target <dupes.txt
fclones dedupe <dupes.txt   # copy-on-write deduplication on some filesystems

Beispiel:

pkolaczk@p5520:~/Temp$ mkdir files
pkolaczk@p5520:~/Temp$ echo foo >files/foo1.txt
pkolaczk@p5520:~/Temp$ echo foo >files/foo2.txt
pkolaczk@p5520:~/Temp$ echo foo >files/foo3.txt

pkolaczk@p5520:~/Temp$ fclones group files >dupes.txt
[2022-05-13 18:48:25.608] fclones:  info: Started grouping
[2022-05-13 18:48:25.613] fclones:  info: Scanned 4 file entries
[2022-05-13 18:48:25.613] fclones:  info: Found 3 (12 B) files matching selection criteria
[2022-05-13 18:48:25.614] fclones:  info: Found 2 (8 B) candidates after grouping by size
[2022-05-13 18:48:25.614] fclones:  info: Found 2 (8 B) candidates after grouping by paths and file identifiers
[2022-05-13 18:48:25.619] fclones:  info: Found 2 (8 B) candidates after grouping by prefix
[2022-05-13 18:48:25.620] fclones:  info: Found 2 (8 B) candidates after grouping by suffix
[2022-05-13 18:48:25.620] fclones:  info: Found 2 (8 B) redundant files

pkolaczk@p5520:~/Temp$ cat dupes.txt
# Report by fclones 0.24.0
# Timestamp: 2022-05-13 18:48:25.621 +0200
# Command: fclones group files
# Base dir: /home/pkolaczk/Temp
# Total: 12 B (12 B) in 3 files in 1 groups
# Redundant: 8 B (8 B) in 2 files
# Missing: 0 B (0 B) in 0 files
6109f093b3fd5eb1060989c990d1226f, 4 B (4 B) * 3:
    /home/pkolaczk/Temp/files/foo1.txt
    /home/pkolaczk/Temp/files/foo2.txt
    /home/pkolaczk/Temp/files/foo3.txt

pkolaczk@p5520:~/Temp$ fclones remove <dupes.txt
[2022-05-13 18:48:41.002] fclones:  info: Started deduplicating
[2022-05-13 18:48:41.003] fclones:  info: Processed 2 files and reclaimed 8 B space

pkolaczk@p5520:~/Temp$ ls files
foo1.txt

Antwort4

Wie testet man Dateien mit einzigartigem Inhalt?

if diff "$file1" "$file2" > /dev/null; then
    ...

Wie können wir eine Liste der Dateien im Verzeichnis erhalten?

files="$( find ${files_dir} -type f )"

Wir können zwei beliebige Dateien aus dieser Liste abrufen und prüfen, ob ihre Namen unterschiedlich, der Inhalt jedoch gleich ist.

#!/bin/bash
# removeDuplicates.sh

files_dir=$1
if [[ -z "$files_dir" ]]; then
    echo "Error: files dir is undefined"
fi

files="$( find ${files_dir} -type f )"
for file1 in $files; do
    for file2 in $files; do
        # echo "checking $file1 and $file2"
        if [[ "$file1" != "$file2" && -e "$file1" && -e "$file2" ]]; then
            if diff "$file1" "$file2" > /dev/null; then
                echo "$file1 and $file2 are duplicates"
                rm -v "$file2"
            fi
        fi
    done
done

Beispielsweise haben wir ein Verzeichnis:

$> ls .tmp -1
all(2).txt
all.txt
file
text
text(2)

Es gibt also nur drei eindeutige Dateien.

Lassen Sie uns dieses Skript ausführen:

$> ./removeDuplicates.sh .tmp/
.tmp/text(2) and .tmp/text are duplicates
removed `.tmp/text'
.tmp/all.txt and .tmp/all(2).txt are duplicates
removed `.tmp/all(2).txt'

Und es bleiben uns nur noch 3 Dateien übrig.

$> ls .tmp/ -1
all.txt
file
text(2)

verwandte Informationen