Скрипт для дедупликации файлов и папок с определенным суффиксом

250
cfp

При неудачном восстановлении OneDrive у меня осталось много файлов и папок с суффиксом «(1)» или «(2)».

Я хотел бы сценарий (Bash хорошо, так как у меня есть MinGW + Cygwin или PowerShell), который будет анализировать все файлы и папки в данной папке (например, "d: \ OneDrive" или "/ cygdrive / d / OneDrive") и для Для каждого файла или папки проверьте, есть ли один или несколько файлов / папок (в одной и той же подпапке), имя файла или папки которых соответствует регулярному выражению "\ 1 \ s * \ (\ d + \) \. \ 2", где "\ 1. "является исходным именем файла / папки без расширения, а \ 2 является исходным расширением. Затем скрипт должен двоично сравнить исходный файл / папку с каждым из файлов / папок, найденных предыдущим регулярным выражением (рекурсивно в последнем случае), и, если они идентичны, он должен удалить копию (ту, которая имеет более длинное имя файла).

Хотя возможная базовая структура скрипта ясна (два вложенных в циклы, поиск для поиска файлов, соответствующих регулярному выражению, сравнение для сравнения и т. Д.) Я недостаточно знаком со скриптами Bash, чтобы удобно соединять части, и вполне может быть более эффективной структурой в любом случае (что помогло бы, учитывая, что нужно пройти около полумиллиона файлов).

0
Я бы ожидал немного больше усилий с вашей стороны, [SU] не является сервисом написания сценариев. Также с PowerShell я бы начал делать Get-FileHash и группировать по Hashes, сохраняя самое короткое имя - отбрасывая другое. LotPings 5 лет назад 0
Честный комментарий! Я добавил первую попытку, которая сейчас выполняется. Пока еще ничего не напечатано, что означает либо ошибку, либо ужасно медленную. cfp 5 лет назад 0
Поскольку это однократная операция, почему бы не использовать WinMerge вручную, который также может сравнивать каталоги? Найти папку с (1) или (2) в ней должно быть довольно легко, а также проверять, существует ли папка без этого суффикса. Seth 5 лет назад 0
В папке и ее подпапках содержится около полумиллиона файлов, и (по некоторым оценкам) не менее 10 000 таких файлов / папок, оканчивающихся на (1) или (2). Вручную вызывать WinMerge такое количество раз было бы довольно болезненно. cfp 5 лет назад 0
Та же самая корневая проблема, другой вопрос: [здесь] (https://superuser.com/q/1338324/432690). Kamil Maciorowski 5 лет назад 0
Спасибо за ссылку на этот другой вопрос. Теперь я ответил на свой вопрос сценарием, который, кажется, работает, хотя он ужасно неэффективен. Если кто-то может создать более быструю версию, это будет высоко ценится. cfp 5 лет назад 0

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

0
cfp

Вот один скрипт, который работает и достаточно эффективен. Обратите внимание, что для работы требуется ровно один пробел до «(1)», а после - ни один.

#!/usr/bin/bash IFS=$'\n'; set -f #Go deepest first to deal with copies within copied folders. for copy in $(find . -regextype posix-egrep -regex "^.*\ \([0-9]+\)\s*(\.[^/.]*)?$" | awk '' | sort -rnk1 | cut -f2-); do orig=$(rev <<< "$copy" | sed -E 's/\)[0-9]+\(\ //' | rev) if [ "$orig" != "$copy" ]; then if [ -f "$orig" ]; then if [ -f "$copy" ]; then echo "File pair: $orig $copy" if diff -q "$orig" "$copy" &>/dev/null; then echo "Removing file: $copy" rm -f "$copy"; fi fi  fi if [ -d "$orig" ]; then if [ -d "$copy" ]; then echo "Folder pair: $orig $copy" if rmdir "$copy" &>/dev/null; then #If the "copy" was an empty directory then we've removed it and so we're done. echo "Removed empty folder: $copy" else #Non-destructively ensure that both folders have the same files at least.  rsync -aHAv --ignore-existing "$orig/" "$copy" &>/dev/null rsync -aHAv --ignore-existing "$copy/" "$orig" &>/dev/null if diff -qr "$orig" "$copy" &>/dev/null; then echo "Removing folder: $copy" rm -rf "$copy"; fi  fi fi fi fi done unset IFS; set +f 

Похожие вопросы