Как можно рекурсивно сравнивать две каталоги и проверить, содержит ли один из каталогов другой?

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

  #!/bin/bash

  # cmp_dir - program to compare two directories

  # Check for required arguments
  if [ $# -ne 2 ]; then
      echo "usage: $0 directory_1 directory_2" 1>&2
      exit 1
  fi

  # Make sure both arguments are directories
  if [ ! -d $1 ]; then
      echo "$1 is not a directory!" 1>&2
      exit 1
  fi

  if [ ! -d $2 ]; then
      echo "$2 is not a directory!" 1>&2
      exit 1
  fi

  # Process each file in directory_1, comparing it to directory_2
  missing=0
  for filename in $1/*; do
      fn=$(basename "$filename")
      if [ -f "$filename" ]; then
          if [ ! -f "$2/$fn" ]; then
              echo "$fn is missing from $2"
              missing=$((missing + 1))
          fi
      fi
  done
  echo "$missing files missing"

Кто-нибудь предложит алгоритм для этого?

1
задан 25 June 2014 в 19:34

2 ответа

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

Установка FSlint

Установка FSlint из программного центра Ubuntu или из командной строки следующим образом:

sudo apt-get install fslint

(В моей системе установка FSlint не зависела от дополнительных зависимостей. В частности, fslint зависит от findutils, python и python-glade2, которые все должны быть в вашей системе. Вы можете удалить FSlint с помощью Software Center или набрав sudo apt-get autoremove --purge fslint в терминале).

Установка FSlint

Запустить FSlint из Unity Dash. [ ! d7]

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

Нажмите кнопку Add в левом верхнем углу, чтобы добавить все каталоги, которые вы хотите проверить. Очевидно, вы можете удалить каталоги с помощью кнопки Remove.

Убедитесь, что установлен флажок recurse? справа. Затем нажмите кнопку Find. (Любые ошибки, такие как проблемы с правами на доступ к файлам, будут напечатаны в нижней части окна FSlint).

FSlint отобразит все дубликаты файлов, их расположение в каталоге и дату файла. FSLint также представляет вам количество байтов, потраченных впустую из-за избыточных файлов.

Удаление дубликатов

Теперь вы можете выбрать несколько файлов с помощью клавиш Shift или Ctrl и левой кнопкой мыши. Если вы хотите выбрать несколько файлов автоматически, нажмите кнопку Select, и вам будут предоставлены такие параметры, как выбор файлов на основе даты или выбор критериев выбора дикой карты.

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

Наконец, вы можете удалить выбранные файлы с помощью кнопки Delete или вы можете объединить выбранные файлы с помощью кнопки Merge. Обратите внимание, что функция Merge удаляет невыбранные файлы из вашей системы и создает жесткие ссылки на соответствующие выбранные файлы. Вы использовали бы эту функцию, если бы хотели сохранить существующую структуру файла, но хотели освободить место в вашей системе.

enter image description here

Удаление дубликатов

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

Существует также Advanced search parameters в верхней части окна FSlint, которая позволяет вам исключать определенные каталоги в вашем поиске или фильтровать результаты с помощью параметров.

В этом простом маленьком инструменте есть множество мощных функций. Это может спасти вас от необходимости писать и отлаживать сценарий. Вы можете узнать больше на http://www.pixelbeat.org/fslint/. Вот прямая ссылка на английский гид: http://en.flossmanuals.net/fslint/.

3
ответ дан 24 May 2018 в 07:21

Я хочу поделиться этим, потому что я думаю, что это довольно забавно.

Для каждой подпапки под целевой папкой мы генерируем хэш для этой подпапки.

Каждая папка hash создается из результата хэширования всех файлов ниже этой папки. Таким образом, любая папка, содержащая идентичные файлы в той же структуре, должна содержать один и тот же хэш!

В конце мы используем uniq для отображения только повторяющихся хэшей папок.

Сохраните следующее скрипт как seek_duplicate_folders.sh, а затем запустите его следующим образом:

$ bash seek_duplicate_folders.sh [root_folder_to_scan]

Вот сценарий:

#!/bin/bash
target="$1"

hash_folder() {
  echo "Hashing $1" >/dev/stderr
  pushd "$1" >/dev/null

  # Hash all the files
  find . -type f | sort | xargs md5sum |

  # Hash that list of hashes, discard the newline character,
  # and append the folder name
  md5sum - | tr -d '\n'
  printf "  %s\n" "$1"

  popd >/dev/null
}

find "$target" -type d |
while read dir
do hash_folder "$dir"
done |
sort |
# Display only the lines with duplicate hashes (first 32 chars are duplicates)
uniq -D -w 32

Предостережения:

Неэффективно: it md5sums файлы в глубину дерева несколько раз (один раз на папку предка) Не обнаруживает различий в временных отметках файла, правах собственности или разрешениях Игнорирует пустые папки. Таким образом, две папки, которые содержат идентичные файлы или файлы, но имеющие разные пустые папки внутри, будут по-прежнему отображаться как идентичные. Игнорирует символические ссылки. Файлы, содержащие разные символические ссылки, все равно могут быть указаны как идентичные.
1
ответ дан 24 May 2018 в 07:21

Другие вопросы по тегам:

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