Задача сравнения двух директорий возникает более-менее часто и стандартные diff+patch под Unix позволяют с ней справиться довольно хорошо, но в моем случае надо было сделать именно архив изменений. На C++/C# программу можно было бы написать за несколько минут, но я задался целью использовать полноценное Unix решение.
Сначала я довольно долго ковырялся с diff, KDiff3 и похожими программами, но результат был очень далек от поставленной задачи, потому было решено писать .sh скрипт. Я совсем не Unix/Linux гуру, потому каждый шаг сопровождался длительным гуглением. :)
Полный файл скрипта: http://runserver.net/temp/ddiff.sh
Список файлов
Для начала надо было получить списки. Вариации команды lr -R выдает нужные файлы, но в неудачном виде и их надо обрабатывать. Дойдя до вида ls -lR|tr -s ' '|cut -d ' ' -f 9, я решил, что терпение закончилось, плюнул на ls и использовал find. У этой команды недостаток в том, что к каждому файлу в добавляется относительный путь. Этого можно избежать, если сначала зайти в папку и делать find ., но тогда по непонятной причине из списка пропадают симлинки, причем использование параметра -type fl не помогает. Нормальным решением оказалось обрезание "лишнего" пути через sed.find $2 | sed -e "s:^$2/::" > files.txt
Перебор и сравнение
Я решил перебирать все файлы из второй папки и проверять, есть ли они в первой. Довольно простой цикл с вызовом cmp:for f in $(cat files.txt)Проверка [ -f "$2/$f" ] нужна, чтобы отсеять директории. Если файл не существует по пути "$1/$f", то он тоже попадает в список, что меня вполне устроило.
do
if [ -f "$2/$f" ]
then
if ! cmp -s "$1/$f" "$2/$f"; then
echo $f >> toadd.txt
fi
fi
done
Архив
Полученный список toadd.txt скармливается команде tar. Чтобы пути в архиве были корректными, приходится делать дополнительный cd:cd $2
tar -czvf ../result.tar.gz --files-from ../toadd.txt
cd ..
Эпилог
В результате потраченного часа времени, у меня теперь есть утилита, позволяющая сравнить, к примеру, две прошивки для какого-то устройства, разные версии репозитариев и пр., а на выходе получить tar.gz (или любой другой) архив с этими отличиями. Конечно, использование diff и patch дало бы гораздо меньший размер, но зато полученный результат гораздо прозрачнее и легче в использовании. Из заметных недостатков этого решения - в архив не попадут пустые директории.Полный файл скрипта: http://runserver.net/temp/ddiff.sh
0 коммент.:
Отправить комментарий