LINUX.ORG.RU

Смотри на checksum.

Ответь честно. Ты же это не для себя, да? Это у вас в вузе такая задачка? А сам ты линуксы наверняка и терпеть не можешь ведь?

matrixd
()
Ответ на: комментарий от matrixd

Нет, почему. Я хочу научиться этому. Я вроде понимаю, что это можно сделать через diff, но там описание под опции довольно не обширное. Поэтому пока не понятно как это делать. Рекурсивно можно 2 разных каталога просмотреть, но чтобы подкаталоги это-то как-то глупо через рекурсию...

Nov
() автор топика
Ответ на: комментарий от matrixd

Да, checksum хорошая идея вместо обхода самих файлов. Но осталась проблема в обходе каталогов и подкаталогов для сравнения... Как два разных каталога сделать это понятно, а вот работать в одном каталоге что-то не очень.

Nov
() автор топика
Ответ на: комментарий от beastie

Checksum соглашусь хорошая идея. Не находил до этого инфу про него. Проблема в обходе каталога и его подкаталогов.

Nov
() автор топика
Ответ на: комментарий от matrixd

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

Nov
() автор топика
Ответ на: комментарий от matrixd

Я бы на пыхтоне писал

Там вроде готовый модуль есть, типа 'findfile' или 'filecmp' не помню точно, но помню что он мог искать с учётом содержимого.

anonymous
()
Ответ на: комментарий от Nov

Как люди не изощраются, лишь бы питон не юзать.

FIL ★★★★
()
Ответ на: комментарий от Nov
import os
from filecpm import cmp

dir1 = '/home/user1'
dir2 = '/home/user2'

for root1, dirs1, files1 in os.walk(dir1):
    for name1 in files1:
        fullname1 = os.path.join(root1, name1)
        print('Files similar to', fullname1)

        for root2, dirs2, files2 in os.walk(dir2):
            for name2 in files2:
                fullname2 = os.path.join(root2, name2)
                if cmp(fullname1, fullname2, shallow=False):
                    print('\t', fullname2)

Не проверял.

anonymous
()
Ответ на: комментарий от Nov

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

matrixd
()
Ответ на: комментарий от beastie

Товарищ программист, скажите, а зачем вам md5 понадобился? Ведь гораздо проще побайтово сравнить файлы, чем читать весь файл, даже если он не совпадает начиная с первого байта, и вычислять не самую простую функцию.

Спасибо.

anonymous
()
Ответ на: комментарий от matrixd

Я до сих пор понять не могу как мне взять файл в директории и сравнить его с другими файлами и поддиректориями в этой директории. И так далее.

Nov
() автор топика
Ответ на: комментарий от anonymous

Ты не понял.. Нужен просто bash без питонов, регистрации и смс.

Nov
() автор топика
Ответ на: комментарий от anonymous

Отвечу за него. А как ты собрался сравнивать _все_ файлы. Ну допустим 300 файлов по 1гб? Каждый из них побайтово сравнивать друг с другом?

matrixd
()
Ответ на: комментарий от matrixd

А, понятно. Действительно, проще сравнить суммы.

anonymous
()
Ответ на: комментарий от Nov

Если тебе файлы между собой сравнить - выше тебе уже описали. Хоть в ста поддиректориях они лежать будут, плевать. Если тебе надо сравнивать директории... Да все точно так же. Если для каждого из файла в директории контрольная сумма уже имеется в словаре/мапе или что у тебя там, и эта мапа относится к какой-то директории - бинго, они совпадают.

matrixd
()
Ответ на: комментарий от matrixd

#!/bin/bash FILES=/path/to/* for f in $FILES do echo «Processing $f file...» # take action on each file. $f store current file name cat $f done

Ты это имеешь в виду?

Nov
() автор топика
Ответ на: комментарий от matrixd

Тогда типа такого что-то:

find . -type f | xargs md5sum | sort -n
anonymous
()
Ответ на: комментарий от beastie

Да чо уж там, петабайты-эксабайты.

Я почти решил :)

find . -type f | xargs md5sum > sums.txt && \
sort -n sums.txt | colrm 33 > all.txt && \
sort -n sums.txt | colrm 33 | uniq | diff all.txt -
anonymous
()
Ответ на: комментарий от anonymous

То неловкое чувство, когда твой двадцатистрочный скрипт можно свернуть в 3 строки. :(
Запощу и свое решение, с эмуляцией словаря в виде каталога с файлами, лол:

#!/bin/bash

TMP_DIR=$(mktemp -d)


for f in $(find . -type f); do
	FN="$TMP_DIR/$(md5sum <$f | cut -d' ' -f1)"
	# echo "Writing <<$f>> to <<$FN>>"
	echo $f >> $FN
done

for f in $(find $TMP_DIR -type f); do
	if [[ $(wc -l <$f) -ge 2 ]]; then
		echo "==== Group $(basename $f) ===="
		cat $f
		echo
	fi
done

echo Done.


rm -rf $TMP_DIR

----------------------------------------

$ ~/find_similar_files.sh 
find: ‘./systemd-private-c289146175f34a47b31fd18a90ada037-systemd-timesyncd.service-QbBMTv’: Permission denied
==== Group 81ae9570a62999be4e8e84ebd3e2533a ====
./tmpl0y8rq
./tmpn7lee3

==== Group 2639e39571fcff02fb55b34edc1b07a6 ====
./mutt-HP250-1000-9193-5902778741208076488
./mutt-HP250-1000-12112-18875756131902173470

==== Group b1946ac92492d2347c6235b4d2611184 ====
./mutt-HP250-1000-11019-7421024681195044009
./mutt-HP250-1000-8290-4752602091921567559

==== Group d41d8cd98f00b204e9800998ecf8427e ====
./tmp.tK40gcR6NR
./lu144049w5vox.tmp/lu144049w5vp0.tmp
./qipc_sharedmemory_homesmolaconfigcopyqcopyqm88728f9f32d36783aab39d4a08476ba8d9e7ee7b
./qipc_systemsem_homesmolaconfigcopyqcopyqm88728f9f32d36783aab39d4a08476ba8d9e7ee7b
./mutt-HP250-1000-8651-1276900788649823015
./mutt-HP250-1000-8651-1414078471996757224
./mutt-HP250-1000-8651-50842814637327189
./dir2/9.txt
./dir2/3.txt
./dir2/2.txt
./dir1/9.txt
./dir1/2.txt
./dir1/1.txt

Done.

Smola
()

Например, соберем чексуммы всех файлов от текущего каталога и ниже и отсортируем по полю с чексуммами, тогда файлики с одинаковыми чексуммами у нас встанут рядом:

for file in `find ./`; do
echo -n «$file» " "; md5sum -c «$file»
done | sort -k 2 | tee ~/result

slowpony ★★★★★
()
Ответ на: комментарий от Smola

Ну а что, отличный скрипт. Вон как всё красиво выводит.

Я тут чутка по манам упоролся и доделал таки:

find . -type f | xargs md5sum > sums.txt && \
sort -n sums.txt | colrm 33 > all.txt && \
sort -n sums.txt | colrm 33 | uniq | diff all.txt - | \
uniq | egrep -o '[0-9a-f]{32}' | \
xargs -I{} grep {} sums.txt
[/bash]

Ерунда, конечно и наверняка где-то ещё срезать можно. 
anonymous
()

Если хочешь оптимизировать по скорости, то я тебе скажу так. Делай два прохода.

  • Первый проход — пройди по всем файлам и составь таблицу их размеров. Из таблицы ты узнаешь, есть ли группы файлов с одинаковыми размерами.
  • Второй проход — внутри этих групп проводишь проверки каждого файла с каждым.
    • Первый этап — сравниваешь первый мегабайт каждого файла в группе + сравниваешь последний мегабайт каждого файла в группе, пропуская всё что в середине.
    • Второй этап — вычисляешь checksum и сравниваешь по ним для тех файлов, которые показали равенство на первом этапе.
justAmoment ★★★★★
()
Ответ на: комментарий от anonymous

Ну там же есть строчка [/bash]. В шары долбишься что ли?

anonymous
()
Ответ на: комментарий от matrixd

Это у вас в вузе такая задачка?

Каждый первый вопрос с тегом «баш» из этой серии. Я уж и читать перестал.

debugger ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.