Как объединить две папки, чтобы удалить из одной одинаковые файлы, сохранив при этом контрольные суммы дифференциалов?

Вы можете попробовать что-то вроде:

VAR=$(sensors | sed -rn 's/.*Core 0:\s+.([0-9]+).*/\1/p'|tr '\n' ' ')

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

.
VAR1=$(echo $VAR|awk '{print $1}')
VAR2=$(echo $VAR|awk '{print $2}')
4
11.01.2021, 22:40
4 ответа

Шаги 2 и 3 кажутся самыми сложными, так что давайте начнем с них.

Существует инструмент под названием rdfind, который находит дубликаты файлов. Вы можете решить, что делать, когда обнаружен дубликат :, в вашем случае вы хотите удалить его из B:rdfind -deleteduplicates true A B. Если в A и B существуют одинаковые файлы, сохраняется файл из A. Другие варианты — заменить копию жесткой или программной ссылкой или просто сообщить о результатах.

Тогда файлы, оставшиеся в B, либо уникальны для B, либо отличаются в B от файлов A. Чтобы переместить уникальные файлы из B в A:mv -i B/* A/и каждый раз отвечать noна вопрос, хотите ли вы перезаписать. Вы можете автоматизировать это с помощью yes no | mv -i B/* A/. Если вы используете GNU mv, вы можете использовать mv --no-clobber B/* A/.

Конечно, вы хотите сначала потренироваться, прежде чем делать это на реальных данных. Вы можете легко создать дерево жестких ссылок на свои файлы в A и B:mkdir training; cp -lr A training; cp -lr B trainingи попрактиковаться там.

3
18.03.2021, 22:37

Вот простой, но неэффективный метод, если в A отсутствует много файлов. Просто выполните каждый шаг по очереди. Я предполагаю, что есть только каталоги и обычные файлы (, сравнение метаданных для специальных файлов выполнимо с немного большей работой ). Предупреждение :непроверенный код.

Во-первых, скопируйте файлы, которые присутствуют в B, но не в A, в A. Максимально сохраните метаданные (, метки времени, разрешения ).

rsync -a --ignore-existing B A

Во-вторых, удалите дубликаты из B. Обратите внимание, что на этом этапе файлы, которых изначально не было в A, теперь идентичны.

cd B
find. -type f -exec sh '
  for x; do
    if cmp -s "$x" "$0/$x"; then rm "$x"; fi
  done
' /path/to/A {} +

При необходимости удалите пустые каталоги из B.

find B -depth -type d -exec rmdir {} + 2>/dev/null

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

2
18.03.2021, 22:37

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

На самом деле проще сначала получить diff, чем вы думаете.

Шаг 1

Получить хэш каждого файла на диске. Тебе все равно придется это сделать.Так что можно было бы покончить с этим и покончить с этим. Приведенная ниже команда хорошо работает, если жестких ссылок не слишком много . Предположим, каталоги называются /media/Aи /media/B.

cd /media/A
find. -type f -exec sha256sum {} + > ~/hashes.txt

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

Шаг 2

Идентифицировать изменения с помощью

cd /media/B
sha256sum -c ~/hashes.txt > ~/check.txt

check.txt теперь будет содержать строки трех типов:

  • good/file: OK
  • missing/file: FAILED open or read
  • changed/file: FAILED

Шаг 3

В качестве ярлыка можно скопировать все отсутствующие файлы с помощью:

rsync -a --ignore-existing /media/A/ /media/B/

Шаг 4

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

grep 'FAILED$' ~/check.txt | while read file ; do
    echo "${file%: FAILED}"
done > ~/changed.txt

Это дает вам измененный.txt, который будет иметь одно имя файла в строке. Каждый файл в обеих системах изменился.

Теперь вы должны отсортировать changed.txtи определить, какие файлы оставить, а какие перезаписать в A из B.

1
18.03.2021, 22:37

если в именах файлов нет "перевода строки", это должно работать:

cd B
find. -type f -print | while read f
do
    [[ -f "A/$f" ]] || { echo mv "$f" "A/$f" ; continue; }
    cmp "$f" "A/$f" && echo rm "$f"
done

Запустите его и, если он выглядит хорошо, удалите слова «эхо», чтобы запустить фактические команды.

1
18.03.2021, 22:37

Теги

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