md5sum файлов в двух папках

md5sum файлов в двух папках

Я пытаюсь сравнить все файлы в двух папках через md5sum в одной команде. Некоторые, как следующие (bash) в Debian:

$ cd ~/FOLDER1
$ md5sum ~/FOLDER2/* | md5sum -c -

Идея заключается в том, что вывод хэшей из первой md5sum будет передан во вторую и использован в качестве входного файла. Однако тестирование этого показывает, что он просто сравнивает каждый файл в FOLDER2 с самим собой и возвращает «OK» для каждого из них. Я думаю, что причина, по которой это не работает, заключается в том, что имена файлов, выводимые из первой md5sum, включают полный путь. Я посмотрел, md5deepно не нашел ничего, что могло бы мне помочь. Я знаю, что можно сделать md5sum для одной папки, записать результаты в файл, а затем использовать этот файл в качестве входных данных для второй md5sum. Я хотел сделать все это в одной строке через конвейер, а не использовать две команды и записывать файл.

Редактировать: Принятый ответздесь(использование diff) может сделать то, что я хочу, но я не знаю, diff(правильно) ли сравниваются двоичные файлы.

Редактировать: Чтобы получить нужный мне вывод с помощью md5sum (который показывает имя файла и «ОК»), я прибегнул к написанию пакетного файла. Выполнить с помощью diffFolders.sh ~/FOLDER1 ~/FOLDER2.

#!/bin/bash
HERE=$PWD
cd "$1"
md5sum * > /tmp/md5sum.cmp
cd "$2"
md5sum -c /tmp/md5sum.cmp
cd $HERE

Этот скрипт будет сравнивать только те файлы, которые присутствуют в ~/FOLDER. Если ~/FOLDER2есть дополнительные файлы, они не будут сравниваться, и вывод не будет указывать на то, что они вообще существуют.

решение1

Вы можете использоватьзамена процессадля передачи вывода 2 md5sum в diff. Diff в этом случае будет в порядке, поскольку вывод md5 представляет собой обычный текст. Что-то вроде:

diff <(md5 ~/FOLDER1/* | awk '{print $4}') <(md5 ~/FOLDER2/* | awk '{print $4}')

Извините, у меня нет Debian, и я не могу проверить это на нем. Вышеизложенное проверено на OS X с md5, который может немного отличаться в плане вывода. На OS X 4-й столбец md5 — это фактическая сумма md5, поэтому я беру только эти столбцы.

Вместо awk вы также можете использовать cut, но вам может потребоваться изменить разделитель, чтобы получить 4-й столбец (они не разделены табуляцией).

решение2

Из моего файла .bashrc.
очень старые вещи, должно быть возможно написать гораздо больше кода сортировщика. Я так и не собрался его переписать. (как и все остальное, что было предназначено для временного исправления, используемого вечно) Я публикую этот позорный кусок кода, надеюсь, кто-то сможет сделать его лучше и опубликовать результат :-)

Функции :

  • Рекрузивный дир поперечный
  • проверка md5sum на уникальность/различие
  • Перечисляет обновленные файлы с указанием полного пути

Код говорит сам за себя. arg1 — старый каталог, arg2 — новый каталог.

function find-updated-files-between-old-new(){
 [ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." > /dev/stderr && return 1;
( ( cat <(cd "$1";find . -type f -printf "+%p\n") <(cd "$2";find . -type f -printf "-%p\n")
 )|sort -k1.2|tee 1>/dev/null >(uniq -us1|awk -v B="$2" 'BEGIN{sub("/$",""B)}/^-/{print B substr($0,3);
 }') >(uniq -ds1|awk -vA="$1" -vB="$2" 'BEGIN{B=g(B);A=g(A)}{
 C=substr($0,3);if(f(A)!=f(B))print B C;}function g(y){sub("/$","",y);return y}
 function f(y,z,e){e="md5sum \""y""C"\"";e|getline z;close(e);return substr(z,1,32)}' )
 ) | cat
}

Как следует из названия функции

function find-files-name-collision-between-dir1dir2(){
 [ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." > /dev/stderr && return 1;
( cat <(cd "$1";find . -type f -printf "+%p\n") <(cd "$2";find . -type f -printf "-%p\n") )|sort -k 1.2 | uniq -d -s 1
}

Просто для полноты картины

function mv-mergedir1todir2(){
 [ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." && return 1;
 ( cd "$1" ; tar cf - . ) | (cd "$2" ; tar --keep-old-files xvf - )
 echo -e "Done. Duplicate filnames are not replaced. \n#Use \n# ( cd \"$1\" ; tar cf - . ) | (cd \"$2\" ; tar --overwrite xvf - ) \n#if you do not like that. "
}

Этот ужасный кусок кода следует удалить из моего bashrc, однако он существует уже долгое время...

решение3

Довольно долго, но возвращает имя файла и OK, если они совпадают. Вместо использования '-c' он просто сравнивает две строки, выведенные при запуске md5sum для файла в каждой папке.

for f in *; do [[ -f $f ]] && if [ $(md5sum "$f" | cut -d" " -f1) == $(md5sum dir2/"$f" | cut -d" " -f1) ]; then echo "$f" "OK"; else echo "$f" "MODIFIED"; fi; done

Связанный контент