1

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

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

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

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

OldDisk1:

/code/{manystructures}/{manyfiles}
/docs/{manystructures}/{manyfiles}

OldDisk2:

/dev/{another_structures}/{same_files_different_names}
/documents/{another_structures}/{same_files_different_names}

NewHugeDisk:

/home/username/code/{new_strutucture}/{new_files}
/home/username/documents/{new_strutucture}/{new_files}

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

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

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

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

3 ответа3

2

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

Просто откройте Powershell ISE (или, если у вас его нет, используйте Блокнот), скопируйте и вставьте в него следующий код и сохраните полученный файл где-нибудь как * .ps1. Вы также должны изменить значения $oldpath и $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).

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

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

  1. Получение всех файлов в указанных папках (и их подпапках)
  2. получить первый старый файл (указанный $ i) ...
  3. сравнивая время последнего редактирования и размер файла с размером первого нового файла (заданного $ j) ...
  4. ... если они равны, он вычисляет хэш файла, чтобы убедиться, что это определенно тот же файл (возможно, это может быть слишком много усилий для вашей цели)
  5. если хэши равны, старый файл удаляется (и он записывает, какой файл в терминале), а затем снова начинается с 2. со следующим старым файлом ...
  6. если хэши не равны (или времена последнего редактирования не равны, или размеры файлов не равны), он начинается снова с 3. со следующим новым файлом.
0

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
0

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

  • у него есть собственный механизм дедупликации для устранения дублирующихся данных, что позволяет сэкономить много места для хранения.
  • Еще одним преимуществом таких инструментов является то, что они более надежны и имеют специальную технику управления ресурсами.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .