1

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

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

Идея состоит в том, что выходные данные хэшей из первой суммы md5 будут переданы во вторую и использованы в качестве входного файла. Однако проверка этого показывает, что он просто сравнивает каждый файл в FOLDER2 с самим собой и возвращает "OK" для каждого. Я думаю, причина этого не в том, что имена файлов, выводимые из первой суммы md5, включают полный путь. Я посмотрел на 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 имеет дополнительные файлы, они не будут сравниваться, и никакие выходные данные не укажут, что они даже существуют.

3 ответа3

2

Вы можете использовать процесс подстановки, чтобы передать выходные данные 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-й столбец (они не разделены табуляцией).

0

Вроде долго, но возвращает имя файла и ОК, если они совпадают. Вместо использования '-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
0

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

Особенности :

  • Рекурсивный dir transversal
  • 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, однако он существует уже давно ...

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .