31

drBatty пишет:

можно проще сделать

$ find . -type f -exec md5sum {} \; | sort | uniq -w32 -d

эта команда показывает ТОЛЬКО те имена файлов, содержимое которых повторяется. Также она показывает их хеш.

Да, но не исключает указанные выше расширения и не предоставляет выбора что и где удалить, а что оставить. В этом плане питон практичней.

-=Serj=- пишет:

drBatty пишет:

    зачем нужен ваш питон?

Пойду выкину его в помойку

Не надо выкидывать то, что реально помогает и нет пока лучшей альтернативы.

32

Lupo Alberto пишет:

Ещё одно маленькое уточнение — find тоже может исключать из поиска по маске имени.

Подскажите, пожалуйста, как? bw

33

Anatoly2012 пишет:

Подскажите, пожалуйста, как? bw

-=Serj=- пишет:

Да, выше уже приводилось:
drBatty пишет:

   

find . ! -name "*.git" ! -name "*.js"
Был, был и весь вышел...

34

Простите, а как правильно будет связать эти команды:
find . -type f -exec md5sum {} \; | sort | uniq -w32 -d
find . ! -name "*.git" ! -name "*.js"

35 (13.10.2013 19:11:02 отредактировано Lupo Alberto)

Anatoly2012 пишет:

Простите, а как правильно будет связать эти команды:
find . -type f -exec md5sum {} \; | sort | uniq -w32 -d
find . ! -name "*.git" ! -name "*.js"

find . ! -name "*.git" ! -name "*.js" -type f -exec md5sum {} \; | sort | uniq -w32 -d

P.S. http://ru.clihelper.com/find/
P.S.S. man find

Был, был и весь вышел...

36

Lupo Alberto и drBatty, еще раз спасибо! bs

37

Lupo Alberto пишет:

P.S. http://ru.clihelper.com/find/
P.S.S. man find

Это читал уже, но мне еще не хватает знания основ работы с командами в консоли, а главное времени. По-тихоньку может научимся...

38

-=Serj=-, а скрипт допилить никак не получится?

39

Anatoly2012, какие требования?

Да, у меня Ubuntu.
Нет, не глючит.

40

-=Serj=- пишет:

исключить некоторые расширения, типа - .gif  .js .HLP .tif .TTF .css .ico .INF .ini .PFB

намекаете на то, что питон умеет регулярки?

man find

-regex pattern
              File  name matches regular expression pattern.  This is a match on the whole
              path, not a search.  For example, to match a file named `./fubar3', you  can
              use the regular expression `.*bar.' or `.*b.*3', but not `f.*r3'.  The regu-
              lar expressions understood by find are by default Emacs Regular Expressions,
              but this can be changed with the -regextype option.

Anatoly2012 пишет:

Да, но не исключает указанные выше расширения и не предоставляет выбора что и где удалить, а что оставить. В этом плане питон практичней.

выбор нужен? И это есть у find

-ok command ;
              Like -exec but ask the user first.  If the user  agrees,  run  the  command.
              Otherwise  just  return false.  If the command is run, its standard input is
              redirected from /dev/null.

              The response to the prompt is matched against a pair of regular  expressions
              to  determine  if  it  is an affirmative or negative response.  This regular
              expression is obtained from the system if the `POSIXLY_CORRECT'  environment
              variable is set, or otherwise from find's message translations.  If the sys-
              tem has no suitable definition, find's own definition  will  be  used.    In
              either  case,  the  interpretation  of the regular expression itself will be
              affected by the environment variables  'LC_CTYPE'  (character  classes)  and
              'LC_COLLATE' (character ranges and equivalence classes).

и вообще, дрова лучше пилить бензопилой. Да, я знаю, ваш швейцарский нож тоже с пилой в комплекте. Но моя бензопила практичнее.

Anatoly2012 пишет:

Не надо выкидывать то, что реально помогает и нет пока лучшей альтернативы.

ой, а мужики-то не знали... А как вы думаете, что делали тогда, когда вашего питона не было?

Anatoly2012 пишет:

Простите, а как правильно будет связать эти команды:

по умолчанию find связывает по "И"

find УСЛОВИЕ1 AND УСЛОВИЕ2 AND УСЛОВИЕ3 AND ДЕЙСТВИЕ

ДЕЙСТВИЕ выполнится тогда, и только тогда, когда все условия истинны. Самое ДЕЙСТВИЕ -- тоже условие, ибо всякая команда выдаёт код возврата, и она истинна, если код равен 0.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

41

-=Serj=- пишет:

Anatoly2012, какие требования?

Чтобы скрипт показывал 2, 3... дубликата и выбор какой файл удалить.

42

drBatty, ваши аргументы не могу оспаривать, но мне проще было через скрипт... пока так понятнее ab

43

drBatty пишет:

намекаете на то, что питон умеет регулярки?

Да не, просто на незавершенность ab

Да, у меня Ubuntu.
Нет, не глючит.

44

Anatoly2012 пишет:

но мне проще было через скрипт... пока так понятнее

find это тоже такой "скрипт" недоделанный. Но для поиска и обработки файлов лучше не бывает.

Если вы думаете, что изучать find не нужно, идите лучше в дворники. Хотя нет, лучше менеджером. Может получится с лозунгом "питона хватит всем!". Ну у BG получилось же!  bm

-=Serj=- пишет:

Да не, просто на незавершенность

мне эта команда даром не нужна.

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

45

drBatty пишет:

Если вы думаете, что изучать find не нужно, идите лучше в дворники. Хотя нет, лучше менеджером. Может получится с лозунгом "питона хватит всем!".

А нафига мешать в кучу знание команд Linux и ЯП?

drBatty пишет:

мне эта команда даром не нужна.

Какая команда? Я говорил про то, чтобы добавить в тот однострок фильтрацию по расширениям.

Да, у меня Ubuntu.
Нет, не глючит.

46

drBatty пишет:

find это тоже такой "скрипт"

-=Serj=- пишет:

А нафига мешать в кучу знание команд Linux и ЯП?

а в чём разница?

-=Serj=- пишет:

Какая команда? Я говорил про то, чтобы добавить в тот однострок фильтрацию по расширениям.

добавьте, кто вам не даёт-то?

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

47 (16.10.2013 16:03:04 отредактировано -=Serj=-)

drBatty, к сожалению, у меня не хватает умения для дальнейшего развития демагогии.

Anatoly2012, если извращённо, то как-то так) :

#!/usr/bin/env python
#_*_ coding: utf-8 _*_

import os
import hashlib
import sys

ignore_list = ['.gif', '.js', '.HLP', '.tif', '.css', '.ico', '.INF', '.ini', '.PFB']

try:
    work_path = sys.argv[1]
except:
    work_path = '.'

md5_dic = {}
dirTree = os.walk(work_path)

def getMd5sum(fname):
    with open(fname) as f:
        return hashlib.md5(f.read()).hexdigest()

for dirPath, dirNames, Files in dirTree:
    for f in Files:
        if os.path.splitext(f)[1] in ignore_list:
            continue
        full_name = os.path.join(os.path.abspath(dirPath), f)
        md5 = getMd5sum(full_name)
        if md5 not in md5_dic:
            md5_dic[md5] = []
            md5_dic[md5].append(full_name)
        else:
            md5_dic[md5].append(full_name)
            
md5_dic = dict((key, val) for key, val in md5_dic.items() if len(val) > 1)

group_num = len(md5_dic)
print('Number of groups duplicate files: %d' % group_num)
i = 1
for key, val in md5_dic.items():
    print('\nGroup %d of %d:' % (i, group_num))
    for f in val:
        print('%5d %s' % (val.index(f) + 1, f))
    print('')
    while True:
        answer = raw_input('Enter file numbers to delete (e.g. 1,3,4). Enter "next" for next group or "exit" to close program.\n> ')
        if answer.strip().lower() == 'next':
            break
        elif answer.strip().lower() == 'exit':
            sys.exit(0)
        try:
            numbers_to_del = set([int(item.strip()) for item in answer.split(',')])
        except:
            print('Error: wrong values!')
            continue
        if numbers_to_del & set(range(1, len(val) + 1)) != numbers_to_del:
            print('Error: wrong values!')
            continue
        print('Delete these files?\n')
        files_to_del = [val[j -1] for j in numbers_to_del]
        for ftd in files_to_del:
            print(ftd)
        while True:
            answer2 = raw_input('\nEnter "yes" or "no":\n> ')
            if answer2.lower() == "yes":
                for ftd in files_to_del:
                    os.remove(ftd)
                break
            elif answer2.lower() == "no":
                break
            else:
                print('Wrong answer!')
                continue
        
        break
    i += 1
$ ./dedup.py target/
Number of groups duplicate files: 2

Group 1 of 2:
    1 /mnt/sandbox/Python/files_dedup/target/folder3/fille3.txt
    2 /mnt/sandbox/Python/files_dedup/target/folder4/fille3.txt

Enter file numbers to delete (e.g. 1,3,4). Enter "next" for next group or "exit" to close program.
> next

Group 2 of 2:
    1 /mnt/sandbox/Python/files_dedup/target/folder1/file1.txt
    2 /mnt/sandbox/Python/files_dedup/target/folder2/file1_copy.txt

Enter file numbers to delete (e.g. 1,3,4). Enter "next" for next group or "exit" to close program.
> 2
Delete these files?

/mnt/sandbox/Python/files_dedup/target/folder2/file1_copy.txt

Enter "yes" or "no":
> yes

ЗЫ. Если по-проще, то, наверное, приведёнными выше командами скинуть имена в файл и уже дальше с ним работать.

Да, у меня Ubuntu.
Нет, не глючит.

48

-=Serj=- пишет:

к сожалению, у меня не хватает умения для дальнейшего развития демагогии.

кроме демагогии есть опыт. Опыт говорит мне, что на некоторых серверах в некоторых продакшенах питона тупо НЕТ. Что вы станете делать в таком практическом случае?

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)

49

drBatty пишет:

Опыт говорит мне, что на некоторых серверах в некоторых продакшенах питона тупо НЕТ. Что вы станете делать в таком практическом случае?

Ну, это аргумент, да... Хотя, неужели нельзя обеспечить безопасность? Тем же bash, perl или php можно дров наломать...
А с третьей стороны, если ты сисадмин, то, хотя бы, основы баш знать, наверное, должен. Мы же python с bash сравниваем, а не с командами?

Да, у меня Ubuntu.
Нет, не глючит.

50

-=Serj=- пишет:

Anatoly2012, ... как-то так) :

Все отлично работает!!!  bp  Еще раз спасибо огромное!  bs  Все сделал, предоволен... За паузу простите, работа...

В скрипте немножко подправил: "next" на "-", "yes" на "y", "no" на "n", и все быстро получилось. Когда попадались два-три дубликата, то meld'ом сравнивал обе директории и одну из них удалял.

P.S. Можно было бы добавить в скрипт строку завершения, например: "поиск завершен", а то, если нет дубликатов в файле скрипт исчезает, - сразу и не поймешь чего это.

51

-=Serj=- пишет:

Хотя, неужели нельзя обеспечить безопасность? Тем же bash, perl или php можно дров наломать...

это не мои сервера. Тамошние админы считают, что от perl'а вреда нет, а вот от питона есть. Школьники шалят. А перловку им не осилить.

-=Serj=- пишет:

А с третьей стороны, если ты сисадмин, то, хотя бы, основы баш знать, наверное, должен. Мы же python с bash сравниваем, а не с командами?

я не понимаю, как сисадмин умудрился не знать команду find??? Да ну и что, что он умеет на каком-то brainfuck'е писать скрипты для поиска?

При чём тут именно bash? Я про find говорил, а не про bash, а вы занимаетесь демагогией, пытаясь перевести стрелки на спор bash vs python.

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

Карусель разнесло по цепочке за час
Всех известий — конец
Да, весна началась!
(всё к лицу подлецу, как родному отцу, не рассказывай, батя, и так всё пройдёт)