Найти и удалить дубликаты файлов на разных дисках и в каталогах

900
Tuts

У меня есть сотни тысяч файлов, распределенных на многих внешних дисках и дисках компьютеров, и многие из них дублированы. Этот беспорядок был вызван тем, что я создал копии для предложения по безопасности. Время от времени я менял структуру каталогов моей организации, но не копировал в других местах, где были копии.

Теперь у меня есть один огромный диск с почти всеми необходимыми мне резервными копиями и зеркальным отражением в облаке.

Я хотел бы получить способ удалить все из всех распределенных дисков, которые уже находятся на большом диске.

Позвольте мне показать сценарий:

OldDisk1:

/code// /docs// 

OldDisk2:

/dev// /documents// 

NewHugeDisk:

/home/username/code// /home/username/documents// 

Кто-нибудь знает инструмент или способ сделать что-то вроде "найти все файлы на OldDisk1, которые уже есть в NewHugeDisk и удалить"?

Я посмотрел на многие инструменты (Windows, Mac и Linux, поскольку у меня есть эта проблема на обоих) бесплатно и платно, но безуспешно.

И идея была бы создать код для этого, но я не разработчик. Я могу делать маленькие и простые коды, но этот вид кода, я думаю, будет сложным для меня.

Я буду признателен за любую помощь или любые идеи на этот счет.

1
Какие инструменты вы пробовали? Как они потерпели неудачу? music2myear 6 лет назад 0
Если вы используете Linux, мне повезло с fslint. Конечно, вы захотите удалить их как явный процесс (не автоматический), но вы можете сгенерировать список имен файлов для сценария удаления или чего-либо еще. Frank Thomas 6 лет назад 0
@ music2myear Я перепробовал много инструментов для Mac, Windows и Linux. Это короткий список, который я пробовал: Easy Duplicate, Duplifinder, Mr Clean, Gemini 2, Dupe Guru, CCleaner, Duplicate File Finder, Auslogics Duplicate File Finder, Disk Drill, Tidy Up, Duplicate Detective, Decloner, Clone Spy, Doppleganger. Есть много других, о которых я читал и даже пытался, но не смог сделать то, что ожидал. Tuts 6 лет назад 0
@Frank Томас, я не пробовал, но, как я читаю, он не сможет выполнить то, что я хочу. Tuts 6 лет назад 0
@ music2myear Я забыл ответить на твой второй вопрос. Все эти инструменты удаляют любой дубликат файла, который он находит по любому указанному вами пути. Допустим, вы предоставляете / old / * и / new / * и только на новых есть /new/dir1/a.txt и /new/dir2/a.txt. это удалит один из тогда. Но я просто хочу удалить файлы в / old / *. Tuts 6 лет назад 0

3 ответа на вопрос

2
flolilolilo

Предполагая, что вы можете использовать Windows в качестве ОС для всего процесса и вам не нравится Free Duplicate File Finder (никогда не пробовал, но нашел его здесь упомянутым ), вы можете использовать PowerShell для достижения того, чего вы хотите, с относительно небольшими усилиями. Примечание: я не настоящий профессионал в PowerShell, поэтому я почти уверен, что можно улучшить мой код.

Просто откройте Powershell ISE (или, если у вас его нет, используйте Блокнот), скопируйте и вставьте в него следующий код и сохраните полученный файл где-нибудь как * .ps1. Вы также должны изменить значения $oldpath's' и $newpath'' '' в ваших каталогах - просто поместите ваши пути между кавычками.

# Search-and-Destroy-script # Get all files of both code-directories: $oldpath = "Disk1:\code" $newpath = "DiskNew:\code"  $files_old = Get-ChildItem -Path $oldpath -Recurse -File $files_new = Get-ChildItem -Path $newpath -Recurse -File  for($i=0; $i -lt $files_old.length; $i++){ $j=0 while($true){ # if last edit time is the same and file-size is the same... if($($files_old[$i]).length -eq $($files_new[$j]).length -and $($files_old[$i]).lastWriteTime -eq $($files_new[$j]).lastWriteTime){ # Get File-Hashes for those files (SHA1 should be enough) $files_old_hash = Get-FileHash -Path $($files_old[$i]).FullName -Algorithm SHA1 | ForEach-Object {$_.Hash} $files_new_hash = Get-FileHash -Path $($files_new[$j]).FullName -Algorithm SHA1 | ForEach-Object {$_.Hash} # if hashes also are the same... if($files_old_hash -eq $files_new_hash){ # remove the old file (-Confirm can be removed so you don't have to approve for every file) # if you want to check the files before deletion, you could also just rename them (here we're adding the suffix ".DUPLICATE" # Rename-Item -Path $($files_old[$i]).FullName -NewName "$($files_old[$i]).Name.DUPLICATE" Remove-Item -Path $($files_old[$i]).FullName -Confirm Write-Host "DELETING`t$($files_old[$i]).FullName" -ForegroundColor Red break } # if files aren't the same... }else{ # if old_file is compared to all new_files, check next old file if($j -ge $files_new.length){ break } } $j++ } } 

Затем запустите скрипт (например, с помощью щелчка правой кнопкой мыши) - если это не удастся, убедитесь, что ExecutionPolicyон установлен ( https://superuser.com/a/106363/703240 ).

Я использую практически идентичный скрипт для проверки файлов, которые уже были скопированы (но, возможно, с измененными именами). Этот код предполагает, что отличаются только имена файлов, но не их содержимое. Время последнего редактирования обычно остается неизменным даже после копирования файла по новому пути - в отличие от времени создания. Если содержимое отличается, моё решение терпит неудачу - вы можете использовать разные уникальные атрибуты файлов (но какие?) Или указать, что, например, только те файлы, которые меньше или старше (учитывая время редактирования, опять же), чем новые файлы, должны быть удален.

Что делает скрипт:

  1. Получение всех файлов в указанных папках (и их подпапках)
  2. получить первый старый файл (указанный $ i) ...
  3. сравнивая время последнего редактирования и размер файла с размером первого нового файла (заданного $ j) ...
  4. ... если они равны, он вычисляет хэш файла, чтобы убедиться, что это определенно тот же файл (возможно, это может быть слишком много усилий для вашей цели)
  5. если хэши равны, старый файл удаляется (и он записывает, какой файл в терминале), а затем снова начинается с 2. со следующим старым файлом ...
  6. если хэши не равны (или времена последнего редактирования не равны, или размеры файлов не равны), он начинается снова с 3. со следующим новым файлом.
Это именно то, что мне было нужно. Спасибо большое. Хотя я мог бы работать только с окнами, чтобы решить свои проблемы, я постараюсь «копировать этот код» (если вы позволите) в bash, так как я смогу поместить его на мой raspiberry pi, чтобы он работал как пока это нужно. Я уже сделал небольшое исправление, так как оно работало некорректно: старая строка `for ($ i = 0; $ i -lt $ files_new.length; $ i ++) {` новая строка` for ($ i = 0; $ i -lt $ files_old.length; $ i ++) {`Когда я создаю сценарий оболочки, я опубликую его здесь. Tuts 6 лет назад 0
Это красиво построенное решение. music2myear 6 лет назад 0
@ Спасибо, я только что исправил эту строку. Я действительно с нетерпением жду получившегося bash-скрипта! flolilolilo 6 лет назад 0
0
user8010482

Вы пытались использовать стороннее программное обеспечение для дедупликации?
Я пробовал дедупликацию морошки, и она действительно эффективна:

  • у него есть собственный механизм дедупликации для устранения дублирующихся данных, что позволяет сэкономить много места для хранения.
  • Еще одним преимуществом таких инструментов является то, что они более надежны и имеют специальную технику управления ресурсами.
Можете ли вы вставить ссылку на программное обеспечение? yass 6 лет назад 0
Пожалуйста, прочтите * [Как я рекомендую программное обеспечение в моих ответах?] (Https://meta.superuser.com/a/5330/432690) * и [отредактируйте] свой ответ соответствующим образом. Kamil Maciorowski 6 лет назад 0
https://www.cloudberrylab.com/dedup-server.aspx user8010482 6 лет назад 0
Я не морошил для дедупликации. Но, глядя сейчас, это программное обеспечение Windows Server (это для моего дома). и все же, не похоже, что это решит мою проблему. у меня есть новый диск и много старых дисков. внутри новых дисков есть дубликаты (на данный момент мне все равно) и может быть дублирование на старых дисках. То, что я не хочу в основном, удалить то, что у меня уже есть на новых дисках. (Новый диск является копией всех других дисков) Tuts 6 лет назад 0
0
thomas_d_j

rmlint - это утилита командной строки с параметрами, позволяющими делать именно то, что вам нужно. Работает на Linux и macOS. Команда, которую вы хотите:

$ rmlint --progress \ --must-match-tagged --keep-all-tagged \ /mnt/OldDisk1 /mnt/OldDisk2 // /mnt/NewHugeDisk 

Это найдет дубликаты, которые вы хотите. Вместо того, чтобы удалять их напрямую, он создает сценарий оболочки (./rmlint.sh), который вы можете просмотреть, при необходимости отредактировать, а затем выполнить, чтобы выполнить желаемое удаление.

Параметр --progress дает хороший индикатор прогресса. «//» отделяет «нетегированные» от «тегированных» путей; пути после «//» считаются «помеченными». «--Must-match-tagged --keep-all-tagged» означает только поиск файлов по непомеченным путям, у которых есть копия в помеченном пути.

Вы также можете сократить эту команду, используя краткий формат параметров:

rmlint -g -m -k /mnt/OldDisk1 /mnt/OldDisk2 // /mnt/NewHugeDisk 
Похоже, это действительно то, что мне нужно. Просто сделал несколько быстрых тестов и выглядит многообещающе. Сделаем еще несколько тестов. Большое спасибо. Tuts 6 лет назад 0
Пожалуйста. Пожалуйста, используйте https://github.com/sahib/rmlint/issues, чтобы сообщить о любых проблемах или предложениях по улучшению thomas_d_j 6 лет назад 0