Как объединить дубликаты папок со структурой «имя (1)», «имя (1) (1)» и т. Д.

461
Josh

Синхронизация между моим Файловым потоком Google, Google Диском и Synology CloudSync и все перепуталось, и у меня остались сотни дубликатов папок с именем папки, за которыми следуют "(1)" или "(2)" и т. Д., И до "(1) (1) (1)".

Знаете ли вы о программе или сценарии, которые могут объединить эти папки?

Пример структуры папок верхнего уровня:

1100 Beetledwarf - Happy ATE 1100 Beetledwarf - Happy ATE (1) 1100 Beetledwarf - Happy ATE (2) 1100 Beetledwarf - Happy ATE (3) 1100 Beetledwarf - Happy ATE (3) (1) 1100 Beetledwarf - Happy ATE (3) (1) (1) 1100 Beetledwarf - Happy ATE (4) 1100 Beetledwarf - Happy ATE (5) 1100 Beetledwarf - Happy ATE (6) 

Поскольку подпапки иногда также имеют ту же проблему, программа или сценарий должны иметь возможность объединять папки, которые следуют этому шаблону именования для всех подпапок, например:

Пример папок 2-го уровня:

1100 Beetledwarf - Happy ATE (6) Analysis Analysis (1) Smirckle_HL Smirckle_HL (2) Pending Reports Photos & Logos 

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

Список вещей, которые я уже пробовал, но ни одна из них не может иметь дело со структурой папок «name (1)» (о которой я могу сказать до сих пор), и все они копируют файлы вместо их перемещения:

  • WinMerge для Windows 10 <- задыхается при попытке скопировать файлы с диска Google (возвращает для них что-то вроде «команда DOS не поддерживается»)
  • Мелд для MacOS. <- медленно.
  • Терминал с командой "ditto" в OS X <- лучший вариант на данный момент.

Спасибо за вашу помощь!

1
Если я вас правильно понял, перемещение файлов в вашем деле через интернет-соединение займет столько же времени, сколько и их копирование. Вы путаете это с перемещением файлов, например * внутри * HD-раздела, это быстро. Перемещение их между разделами, между жесткими дисками, между ПК и т. Д. Обычно занимает значительно больше времени (не считая исключения в определенных конфигурациях). Albin 5 лет назад 0
Спасибо, я удалил немного о моем интернет-соединении, потому что оно постороннее. При использовании файлового потока Google в Windows и Mac OS, если вы перемещаете файлы, это похоже на перемещение файлов внутри HD-раздела: если вы перемещаете файлы, ОС обычно просто изменяет указатели, которые указывают на файл, но если вы копируете их, Затем ОС обычно копирует данные в новое место на диске. В этом случае копирование занимает еще больше времени, поскольку HD подключен через Интернет. Ура! Josh 5 лет назад 0
Всем привет. Я работаю над сценарием Pyhton, чтобы конкретно решить ваш вопрос. Он достаточно готов, но, к сожалению, я не могу тратить больше времени на (важные) последние штрихи (меры предосторожности) до понедельника = /, так как я буду путешествовать. Если вы натолкнулись на ответ до этого, хорошо - в любом случае, отлично подходит для вас = D, но если вы его не найдете, я могу закончить и опубликовать его здесь как ответ =). Хорошего дня. Vinícius M 5 лет назад 0

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

1
Kamil Maciorowski

Это подход, который я бы попробовал в Linux. У меня нет опыта работы с Google Filestream, Google Drive и Synology CloudSync, поэтому я не могу сказать, можно ли применить решение вообще. Тем не менее, я надеюсь, что это, по крайней мере, даст вам некоторые идеи.


Предположения

  • Вы можете установить долю дерева каталогов, поэтому mv, cpи другие нормальные инструменты могут работать с каталогами, как если бы они были локальными;
  • файлы (или каталоги) с путями, которые становятся идентичными после удаления всех (N)строк, фактически являются экземплярами одного и того же файла (каталога);
  • экземпляры одного и того же файла должны оставлять только один файл;
  • экземпляры одного и того же каталога должны объединять их содержимое в одном каталоге;
  • Вы можете использовать все инструменты, которые я использую здесь.

Процедура

Пожалуйста, прочитайте весь ответ, прежде чем пытаться что-либо сделать.

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

  1. В оболочке cdк точке монтирования и вызова find . | vidir -; используйте текстовый редактор по вашему выбору, например kate, так:

    find . | EDITOR=kate vidir 

    Откроется редактор со списком всех объектов, каждый со своим номером впереди. Когда вы изменяете содержимое, сохраняете (временный) файл и закрываете редактор, все изменения применяются. В общем, это то, что вы можете сделать:

    • изменить пути для перемещения (переименования) файлов или каталогов;
    • удалять строки для удаления файлов или каталогов;
    • поменяйте местами два или более номеров, чтобы поменять файлы (вам это не понадобится).

    Не сохраняйте файл, если вы не уверены, что новый контент описывает дерево каталогов, которое вы хотите получить.

  2. Скопируйте содержимое из редактора в другой файл. Суть в том, чтобы работать с ним и вставлять результат обратно (и сохранять его) только тогда, когда вы уверены, что все правильно поняли. Следующие шаги относятся к новому файлу, если явно не указано иное.

  3. Используйте sedили любой другой инструмент, чтобы избавиться от всех (N)строк (обратите внимание на начальный пробел). На этом этапе вы должны получить «чистые» пути, многие из которых будут встречаться более одного раза (с разными номерами, заданными vidir).

  4. Используйте sort -k 2для сортировки по этим путям. Благодаря -sпервому Analysisвсе еще должно предшествовать первое Analysis (1).

  5. Используйте uniq -f 1для удаления дублированных путей. Теперь любой путь должен пройти только один раз.

  6. Дважды проверьте работоспособность структуры каталогов, закодированных в результате.

  7. Вставьте результат в оригинальный редактор, сохраните файл и выйдите из редактора. vidirудалит объекты, связанные с отсутствующими номерами, и переместит объекты, связанные с оставленными номерами.


тестирование

Сначала я бы использовал это решение для репликации структуры каталогов:

cp -a --attributes-only /mountpoint/ /guinea_pig_dir/ 

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


Возможные проблемы

  1. vidir отказывается работать с некоторыми нестандартными персонажами.

  2. Вообще порядок объектов важен. Есть несколько ловушек, которые генерируют такие объекты, как foo~или foo~1, foo~2когда происходит столкновение с foo. Вы будете «сокращать» дерево каталогов таким образом, чтобы не возникало коллизий, но я не исследовал все возможные сценарии. Я действительно думаю, что вы должны поэкспериментировать с /guinea_pig_dir/и посмотреть, что вы получите. В случае неприятностей может быть умный sortмежду findи vidirпоможет.

1
cfp

Ниже приведен скрипт bash, который выполняет эту задачу. Работает, например, на MSYS2 Bash с добавленным rsync. Это взято из этого связанного вопроса здесь:

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

#!/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 
Как бы я установить начальный каталог в этом скрипте? Как при тестировании, так и при окончательном развертывании я хочу, чтобы он работал только с определенным подмножеством моих файлов. Пример: 'G: \ My Drive \ Deduplicate_Test_Folder' PS: Спасибо за невероятный ответ! Josh 5 лет назад 0
Просто начните в этой папке. (То есть `cd` там.) cfp 5 лет назад 0

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