Viime aikoina minun on poistettava paljon kaksoiskappaleita. Yhdistän kolme tai neljä tiedostojärjestelmää ja haluan, että tilaa käytetään taloudellisesti. Aluksi fdupes näytti siltä, että se oli paras työkalu työhön, mutta minulla on yhä enemmän rajoituksia.

Harkitse komentoa fdupes -rdN somedirectory/. Tämä tekee hajautuksen kaikista tiedostoista jonkin hakemiston alihakemistoissa.

Ja kun se havaitsee kaksoiskappaleita, se poistaa ne, joten kaikesta on vain yksi kopio.

Mutta entä jos haluan säilyttää somedirectory/subdirectory1/somefile ja itse asiassa on neljä kaksoiskappaletta, ja ohjelma kohtaa ensin yhden kaksoiskappaleista? Sitten se poistaa somedirectory/subdirectory1/somefile, jota en halua.

Haluan pystyä jotenkin määrittelemään, mitkä kopiot säilytetään. Ja toistaiseksi mikään kaksoiskappaleiden käsittelyyn tarkoitettujen vakio-ohjelmien (duff, FSLint) näyttävät mahdollistavan tällaisen käyttäytymisen automatisoinnin. En haluaisi, että en tekisi omaa, joten siksi kysyn tämän kysymyksen.

Haluaisin pystyä kirjoittamaan jotain sellaista:

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

Kommentit

vastauksen

Vaikka etsimääsi toimintoa ei ole varastossa fdupes, haarauin fdupes (haarukkaa kutsutaan nimellä jdupes) ja lisättiin joitain ominaisuuksia, jotka voivat ratkaista tämän ongelman tietyissä olosuhteissa. esimerkki ilmoitetussa tapauksessa, jossa haluat säilyttää somedirectory/subdirectory1/somefile kun kaksoiskappaleet poistetaan automaattisesti (d ja N kytketään yhteen), eikä somedirectory, jdupes voidaan syöttää jokaiselle välittömälle alihakemistopolulle subdirectory1 ensin ja -O -kytkin (joka lajittelee tiedostot ensin komentoriviparametrijärjestyksessä):

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

Tämä poistaa automaattisesti kaikki paitsi yhden tiedoston kaksoiskopiosta ja takaa, että jos sarja sisältää tiedoston somedirectory/subdirectory1, se on ensimmäinen, jolloin siitä tulee automaattisesti ryhmän säilytetty tiedosto . Tällä lähestymistavalla on edelleen räikeitä rajoja, kuten se, että toinen kopio somedirectory/subdirectory1 -palvelussa voidaan säilyttää sen sijaan, että halusit säilyttää, mutta monissa tapauksissa sinun kaltaisissasi tapauksissa jdupes -parametritilausvaihtoehto kiertotapana on tarpeeksi hyvä.

Aion lisätä lähitulevaisuudessa suodatusjärjestelmän kohtaan jdupes joka mahdollistaa valtavan määrän hallintaa tiedostojen sisällyttämisessä / poissulkemisessa, -N -toimintojen säilyttämisessä ja tällaisten ”suodatinpinoiden” soveltamisessa joko maailmanlaajuisesti tai per -parametri. Tätä ominaisuutta tarvitaan kipeästi; Kuvittelen jotain tällaista ”poistaa nollasta poikkeavat kaksoiskappaleet rekursiivisesti, mutta säilytä aina somedirectory/subdirectory1/somefile sellaisena kuin se on”:

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

Vastaa

En nähnyt tätä missään muualla: Sano mitä haluat. / mnt / folder-tree-1 / mnt / folder-tree-2. Et halua poistaa kaikkia dupe-tiedostoja, mutta jos puu-2: ssa on tiedosto ja puu-1: ssä on identtinen tiedosto, täsmälleen sama polku ja nimi, poista se puusta 2.

Varoitus: tämä on melko lyhyt, ja jos yrität kopioida-liittää tämän rajoitetuilla kuoritaidoilla, ole varovainen.

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 

Tai kaikki yhdellä rivillä:

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 

Tarkasta ja suorita jälkeenpäin rm-v2-dupes.sh

vastaus

Entä kaksoiskappaleiden sitominen yhteen? Tällä tavalla tilaa käytetään vain kerran, mutta niitä on edelleen kaikilla poluilla. Tämän takana on, että kovakytkettyjä tiedostoja tulisi muuttaa paikalleen (niitä tulisi muokata vain poistamalla tiedosto ja luomalla se uudella sisällöllä). Toinen tapa on linkittää tiedostot yhteen, vaikka sinulla on sama asia päättää, mikä ”ensisijainen” tiedosto on. Tämä voidaan tehdä seuraavalla komentosarjalla (vaikka huomaa, että tämä ei käsittele välilyöntejä sisältäviä tiedostonimiä).

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

Kommentit

  • jdupes : n käyttäminen fdupes voit yksinkertaisesti siirtyä jdupes -nrL somedirectory/, joka on huomattavasti nopeampi.
  • Kirjoitusvirhe jdupes-linkissä. Mukavuuslinkki: github.com/jbruchon/jdupes

vastaus

Minulla oli sama kysymys.Jos sinulla on useita kaksoiskappaleita, fdupes /my/directory/ -rdN pitää tiedoston, jolla on vanhin muokkauspäivä, tai jos useilla tiedostoilla on sama muokkauspäivämäärä, sitten ensimmäinen löytyi.

Jos muokkauspäivä ei ole sinulle tärkeä, voit touch säilyttää haluamasi hakemiston tiedostot. Jos valitset touch heille nykyisen päivämäärän ja kellonajan, fdupes -rdNi säilyttää nykyisen päivämäärän. Tai voit touch säilyttää tiedostot, joiden päivämäärä on aikaisempi kuin poistettavien tiedostojen päivämäärä, ja käyttää fdupes -rdN normaalisti.

Jos sinun on pidettävä muokkauspäivämäärä, sinun on käytettävä jotain muuta tapaa.

Vastaa

Vain lisätä kierre edelliseen vastaukseen. Olen käyttänyt seuraavaa koodia useita kertoja, muokkaamalla hieman edellistä vastausta yksinkertaisella | grep -toiminnolla poistettavan kansion eristämiseksi.

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

Jälleen tämä luo sh-tiedoston kaikkien luettelossa olevien tiedostojen poistamiseksi, ei kommentoituja rivejä. Voit tietysti edelleen muokata tiedostoa kommentoidaksesi tiettyjä rivejä / tiedostoja, jotka haluat säilyttää.

Toinen vihje suurille hakemistoille on ajaa fdupes txt-tiedostoon ja kokeilla sitten | grep ja | sed, kunnes saan haluamasi tulos.

`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` 

Vastaa

Käytä sed luodaksesi komentotiedoston, joka sisältää kommentoidut komennot kaikkien päällekkäiset tiedostot:

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

Tuloksena oleva remove-duplicate-files.sh tiedosto Juuri luomamme kukin rivi kommentoidaan. Kommentoi poistettavia tiedostoja. Suorita sitten sh remove-duplicate-files.sh . Voila!

PÄIVITYS

No, jos et halua poistaa tiedostoja vain tietyistä hakemistoista, se on niin yksinkertaista kuin tämä :

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 

Missä exclude_duplicates.py on:

 #/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)  

Tuloksena saatu remove-duplicate-files-keep-protected.sh tiedosto, jonka olemme juuri luoneet, kommentoi kaikkia suojattujen hakemistojen tiedostoja. Avaa tämä tiedosto suosikkitekstieditorissasi, tarkista, että kaikki on kunnossa. Suorita sitten. Voila (sic)!

Kommentit

  • ajattelin tätä, mutta se ’ ei ole tarpeeksi automatisoitu. Tyhmästi aiheutin tietojen menetystä tällä menetelmällä, kun useiden tiedostojärjestelmien toisistaan toisistaan poikkeavien kopioiden käsitteleminen … ’ ei ole mitään tapaa antaa prioriteettia fdup-lähdön perusteella es. pohjimmiltaan minun olisi pitänyt troolata 10000 tiedostoa käsin tietojen menetyksen estämiseksi … joten ei kiitos … itse asiassa, että tietojen menetys on juuri syy, miksi esitin tämän kysymyksen.
  • @ixtmixilix, no, manuaalinen menetelmä riippuu käyttäjän tarkkaavaisuudesta, tässä ’ ei ole mitään uutta. Jos haluat jotain automatisoitua, maksa päivitetty vastaus yllä.

Vastaa

Entä tällainen?

#!/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 

vastaus

Apple File Filesystem (APFS) -versio on pitää tiedostot, kopioida ne, eikä sillä ole vaikutusta levyn käyttöön. Katso Korvaa APFS: n olemassa olevat kaksoiskappaleet klooneilla

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *