Nemrégiben sok másolat törlésére van szükségem. Három vagy négy fájlrendszert egyesítek, és azt akarom, hogy a helyet gazdaságosan használják. Eleinte úgy tűnt, hogy a fdupes a legjobb eszköz a munkához, de egyre inkább korlátokba ütközök.

Vegye figyelembe a . Ez kivonatolja az összes fájlt a valamilyen könyvtár alkönyvtáraiban.

És amikor ismétlődésekkel találkozik, törli őket, így mindenből csak egy példány van.

De mi van, ha meg akarok tartani somedirectory/subdirectory1/somefile és valójában négy példány létezik, és a program először találkozik az egyik duplikátummal? Ezután törli a somedirectory/subdirectory1/somefile fájlt, amelyet nem akarok.

Szeretném valahogy megadni, hogy melyik másolatot kell megtartani. És egyelőre sem úgy tűnik, hogy a másolatok kezelésére szolgáló szokásos programok (duff, FSLint) lehetővé teszik az ilyen viselkedés automatizálását. Inkább nem szeretném a sajátomat forgatni, ezért “teszem fel ezt a kérdést.

Szeretnék ilyet írni:

killdupes -rdN --keep=filesin,somedirectories,separated,by,commas somedirectory/ 

Megjegyzések

választ

Bár a keresett funkció nem áll rendelkezésre fdupes, én elágaztam fdupes (a villám neve: jdupes) , és hozzáadott néhány olyan funkciót, amelyek bizonyos körülmények között megoldják ezt a problémát. például abban az esetben, ha meg akarja tartani a a duplikátumok automatikus törlésénél (a d és a N kapcsolók együtt kapcsolnak), és a somedirectory, jdupes minden közvetlen alkönyvtár-útvonalat előbb subdirectory1 és a -O kapcsoló (amely először fájlokat rendez a parancssori paraméterek sorrendje szerint):

jdupes -nrdNO somedirectory/subdirectory1 somedirectory/subdirectory2 somedirectory/subdirectory3

Ez automatikusan törli az összes fájlt egy kivételével egy duplikátumkészletben, és garantálja, hogy ha a halmaz tartalmaz egy fájlt a somedirectory/subdirectory1 fájlban, akkor ez lesz az első, és ezáltal automatikusan a készlet megőrzött fájljává válik . Ennek a megközelítésnek még mindig vannak kirívó korlátai, például az a tény, hogy a somedirectory/subdirectory1 fájlban meg lehet őrizni egy másik másolatot a megtartani kívánt helyett, de nagyon sok esetben, mint a tiéd, A jdupes paraméter sorrend opciója megoldásként elég jó.

A közeljövőben egy szűrőrendszert tervezek hozzáadni a amely lehetővé teszi a fájlok beillesztésének / kizárásának hatalmas ellenőrzését, a -N műveletek megőrzését és az ilyen “szűrőkészletek” alkalmazását globális vagy külön-külön. -paraméter alapon. Erre a funkcióra nagyon szükség van; Valami ilyesmit úgy képzelem el, hogy “a nullától eltérő duplikátumok automatikus törlése rekurzív módon, DE mindig megőrizze a somedirectory/subdirectory1/somefile állapotot:

jdupes -nrdN --filter=preserve:somedirectory/subdirectory1/somefile somedirectory/

Válasz

Nem láttam ezt sehol máshol: Mondd, amit akarsz. / mnt / folder-tree-1 / mnt / folder-tree-2. Nem akarsz minden dupe-ot eltávolítani, de ha egy fájl létezik a fa-2-ben, és egy azonos fájl létezik a tree-1-ben, pontosan ugyanazokkal elérési út és név, távolítsa el a fa-2-ből.

Figyelmeztetés: ez elég szűkszavú, és ha korlátozott shell-készséggel próbálja ezt másolni-beilleszteni, legyen óvatos.

fdupes -rn /mnt/folder-tree-1/ /mnt/folder-tree-2/ > dupes-all.txt fgrep /mnt/folder-tree-1/ dupes-all.txt | while read line do if grep -q "`echo $line | sed -e "s|^/mnt/folder-tree-1/|/mnt/folder-tree-2/|"`" dupes-all.txt then echo rm \"$(echo $line | sed -e "s|^/mnt/folder-tree-1/|/mnt/folder-tree-2//|")\" fi done > rm-v2-dupes.sh 

Vagy mindez egy sorban:

fdupes -rn /mnt/folder-tree-1/ /mnt/folder-tree-2/ > dupes-all.txt; fgrep /mnt/folder-tree-1/ dupes-all.txt | while read line; do if grep -q "`echo $line | sed -e "s|^/mnt/folder-tree-1/|/mnt/folder-tree-2/|"`" dupes-all.txt; then echo rm \"$(echo $line | sed -e "s|^/mnt/folder-tree-1/|/mnt/folder-tree-2/|")\"; fi; done > rm-v2-dupes.sh 

Utána ellenőrizze és hajtsa végre az rm-v2-dupes.sh

Válasz

Mi van a duplikált fájlok összekapcsolásával? Így a teret csak egyszer használják, de még mindig léteznek az összes ösvényen. Az a fogás, hogy a merevhivatkozású fájlokat a helyükön módosítani kell (azokat csak a fájl törlésével és az új tartalommal való újrateremtéssel lehet módosítani). A másik megközelítés a fájlok összekapcsolása, bár ugyanaz a kérdés, hogy eldöntse, melyik az „elsődleges” fájl. Ez megtehető a következő szkript segítségével (bár vegye figyelembe, hogy ez nem kezeli a szóközöket tartalmazó fájlneveket).

fdupes --quiet --recurse --sameline somedirectory/ | while read SOURCE DESTS; do for DEST in $DESTS; do ln -f $SOURCE $DEST done done 

Megjegyzések

  • A jdupes használata fdupes helyett egyszerűen elmehet jdupes -nrL somedirectory/, amely jelentősen gyorsabb.
  • Gépelési hiba a jdupes linkjében. Kényelmi link: github.com/jbruchon/jdupes

Válasz

Ugyanaz a kérdésem volt.Ha sok másolat van, akkor fdupes /my/directory/ -rdN a legrégebbi módosítási dátumot tartja meg, vagy ha több fájlnak ugyanaz a módosítási dátuma, akkor az elsőnek talált.

Ha a módosítás dátuma nem fontos az Ön számára, touch fájlokat tárolhat a megtartani kívánt könyvtárban. Ha úgy dönt, hogy touch az aktuális dátummal és idővel, akkor a fdupes -rdNi megtartja az aktuális dátumot. Vagy touch megtarthatja a törölni kívánt fájloknál korábbi dátumú fájlokat, és a szokásos módon használhatja a fdupes -rdN fájlt.

Ha meg kell őriznie a módosítás dátumát, akkor a többi módszer egyikét kell használnia.

Válasz

Csak egy csavar hozzáadása az előző válaszhoz. A következő kódot többször is felhasználtam, egy korábbi | grep egyszerű változtatással módosítva a korábbi választ, hogy elkülönítsem a törölni kívánt mappát.

`fdupes -r -n -S /directory | grep /delete-from-directory | sed -r "s/^/rm \"/" | sed -r "s/$/\"/" >remove-duplicate-files.sh` 

Ismételten létrehoz egy sh fájlt az összes felsorolt fájl törléséhez, megjegyzés nélküli sorok nélkül. Természetesen továbbra is szerkesztheti a fájlt, hogy megjegyezze azokat a sorokat / fájlokat, amelyeket meg akar tartani.

A nagy könyvtárak másik tippje az, hogy az fdupes fájlokat futtatja egy txt fájlba, majd kísérletezzen a | grep és | sed elemekkel, amíg meg nem kapom a kívánt eredményt.

`fdupes -r -n -S /directory > duplicate-files.txt` `cat duplicate-files.txt | grep /delete-from-directory | sed -r "s/^/rm \"/" | sed -r "s/$/\"/" >remove-duplicate-files.sh` 

Válasz

A sed használatával hozzon létre egy shell fájlt, amely kommentált parancsokat tartalmaz az egyes fájlok törléséhez. duplikált fájlok:

fdupes -r -n -S /directory | sed -r "s/^/#rm \"/" | sed -r "s/$/\"/" >remove-duplicate-files.sh 

Az eredményül kapott remove-duplicate-files.sh fájl Az imént létrehozott sorok mindegyikét kommentálják. Kommentálja a törölni kívánt fájlokat. Ezután futtassa az sh remove-duplicate-files.sh parancsot. Voálá!

UPDATE

Nos, ha csak bizonyos könyvtárakban akarsz fájlokat törölni, akkor ez ilyen egyszerű :

fdupes -S /directory|sed "/^$/d" |sed -r "s/^[0-9]/#&/" > duple_list python exclude_duplicates.py -f /path/to/dupe_list --delimiter="#" --keep=/full/path/to/protected/directory1,/full/path/to/protected/directory2\ with\ spaces\ in\ path >remove-duplicate-files-keep-protected.sh 

Hol van exclude_duplicates.py:

 #/usr/bin/python # -*- coding: utf-8 -*- # exclude_duplicates.py """ THE SCRIPT DOESN"T DELETE ANYTHING, IT ONLY GENERATES TEXT OUTPUT. Provided a list of duplicates, such as fdupes or fslint output, generate a bash script that will have all duplicates in protected directories commented out. If none of the protected duplicates are found in a set of the same files, select a random unprotected duplicate for preserving. Each path to a file will be transformed to an `rm "path"` string which will be printed to standard output. """ from optparse import OptionParser parser = OptionParser() parser.add_option("-k", "--keep", dest="keep", help="""List of directories which you want to keep, separated by commas. \ EXAMPLE: exclude_duplicates.py --keep /path/to/directory1,/path/to/directory\ with\ space\ in\ path2""", metavar="keep" ) parser.add_option("-d", "--delimiter", dest="delimiter", help="Delimiter of duplicate file groups", metavar="delimiter" ) parser.add_option("-f", "--file", dest="file", help="List of duplicate file groups, separated by delimiter, for example, fdupes or fslint output.", metavar="file" ) (options, args) = parser.parse_args() directories_to_keep = options.keep.split(",") file = options.file delimiter = options.delimiter pretty_line = "\n#" + "-" * 35 print "#/bin/bash" print "#I will protect files in these directories:\n" for d in directories_to_keep: print "# " + d print pretty_line protected_set = set() group_set = set() def clean_set(group_set, protected_set, delimiter_line): not_protected_set = group_set - protected_set while not_protected_set: if len(not_protected_set) == 1 and len(protected_set) == 0: print "#randomly selected duplicate to keep:\n#rm "%s"" % not_protected_set.pop().strip("\n") else: print "rm "%s"" % not_protected_set.pop().strip("\n") for i in protected_set: print "#excluded file in protected directory:\n#rm "%s"" % i.strip("\n") print "\n#%s" % delimiter_line file = open(file, "r") for line in file.readlines(): if line.startswith(delimiter): clean_set(group_set, protected_set, line) group_set, protected_set = set(), set() else: group_set = group_set|{line} for d in directories_to_keep: if line.startswith(d): protected_set = protected_set|{line} else: if line: clean_set(group_set, protected_set, line)  

Az eredményül kapott remove-duplicate-files-keep-protected.sh fájlban a védett könyvtárak összes fájlját megjegyzik. Nyissa meg ezt a fájlt a kedvenc szövegszerkesztőben, ellenőrizze, hogy minden rendben van-e. Ezután futtassa. Voila (sic)!

Megjegyzések

  • gondoltam erre, de ez ‘ nem elég automatizált. Bután, ezzel a módszerrel adatvesztést okoztam, amikor több fájlrendszer között elhelyezett duplikátumok kezelése … ‘ nincs mód prioritás hozzárendelésére, tekintettel az fdup kimenetére es. alapvetően 10000 fájlt kellett volna kézzel vonszolnom, hogy megakadályozzam ezt az adatvesztést … szóval, köszönöm … valójában ez az adatvesztés az oka annak, hogy feltettem ezt a kérdést.
  • @ixtmixilix, nos, a manuális módszer a felhasználó figyelmességétől függ, itt ‘ nincs semmi újdonság. Ha valami automatizáltabb dolgot szeretne, akkor nézzen meg egy frissített választ fent.

Válasz

Mi a helyzet ilyesmivel?

#!/bin/bash DUPE_SEARCH_DIR=somedir/ PREFERRED_DIRS=("somedir/subdir1" "somedir/subdir2") DUPE_FILE=/tmp/`basename $0`_found-duplicates delete_dupes() { while read line ; do if [ -n "$line" ] ; then matched=false for pdir in "${PREFERRED_DIRS[@]}" ; do if [[ $line == $pdir/* ]] ; then matched=true break fi done if ! $matched ; then rm -v "$line" fi fi done < "$DUPE_FILE" } cleanup() { rm -f $DUPE_FILE } trap cleanup EXIT # get rid of normal dupes, preserve first & preserve preferred fdupes -rf "$DUPE_SEARCH_DIR" > $DUPE_FILE delete_dupes # get rid of preserve dupes, preserve preferred fdupes -r "$DUPE_SEARCH_DIR" > "$DUPE_FILE" delete_dupes 

Válasz

Az Apple Filesystem (APFS) óta egy másik megoldás a fájlok megőrzése, deduplikálása, és nincs hatással a lemez használatára. Lásd: Az APFS meglévő duplikált fájljainak cseréje klónokkal

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük