Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Поиск дубликатов (http://forum.oszone.net/showthread.php?t=235875)

Baranius 03-06-2012 14:29 1927229

Поиск дубликатов
 
Привет, всем.
Вот упрощённый вид задачи: в списке из ~10 000 строк (6,7-значные числа) найти повторяющиеся значения - дубликаты.
Решаема ли такая задача силами CMD\BAT, VBS скриптов или это уже из сферы БД, Excel-я?

Anonymоus 03-06-2012 16:01 1927264

Baranius, попробуйте вот это.
Код:

@Echo Off
Set File=test.txt

rem Разбираем файл построчно
For /F "usebackq delims=" %%S In ("%File%") Do (
    rem Проводим в нём же поиск по отдельно взятой строке и получаем количество совпадений
    For /F "tokens=3 delims=: " %%C In ('Find /C "%%S" "%File%"') Do (
        rem Сортируем строки по разным спискам
        If "%%C"=="1" (
            Echo %%S>>"checked.txt"
        ) Else (
            Echo %%S>>"duplicated.txt"
        )
    )
)

В качестве файла допустимо указывать только относительный путь (чтобы избежать появления в строке, выдаваемой Find ещё одного двоеточия). Кроме того, есть некоторая неточность в поиске данным методом - например, Find найдет и пометит, как дубликат строку "123", если в файле ещё будут присутствовать строки "1234" и "a123"
Впрочем, для вашей задачи (поиск дубликатов песен по их длительности) это особой роли не играет, вероятность совпадения из-за такого поведения Find крайне ничтожна.

Iska 03-06-2012 22:54 1927500

Цитата:

Цитата Baranius
найти повторяющиеся значения - дубликаты. »

И что с ними делать?

Baranius 04-06-2012 01:42 1927561

Цитата:

Цитата Iska
найти повторяющиеся значения - дубликаты. »
И что с ними делать? »

- да Вы просто их найдите, и дайте об этом знать хоть списочком каким, хоть другим способом. Вопрос - возможно ли это силами CMD\BAT, VBS скриптов?

Baranius 04-06-2012 03:55 1927590

Уважаемый Anonymоus, я рад Вас видеть в этой теме, которая навеяна нашим неравноправным общением по вопросу... "как не потерять старый плейлист после наведения порядка на диске" И чтобы не настаивать на
хотелке
почему батник, когда встречает три одинаковых файла (песня_1 (на рис. - Mr Saxobeat), не записывает их в результат (NEW.plc) - это было бы здорово, это тот отличный побочный результат (поиск дубликатов), который был бы очень полезен.

мне подумалось, что легче, для начала, избавиться от дубликатов, а потом уж приводить в порядок старый плейлист. Поэтому и появилась эта тема (я постеснялся вновь обращаться к Вам, к тому же правила форума - "один вопрос - одна тема")

Baranius 04-06-2012 15:01 1927811

Спасибо, Anonymоus! Всё чудесно работает (взял только один столбец с длительностью и представил его как "test.txt"). Но вот с этим:
Цитата:

Цитата Anonymоus
В качестве файла допустимо указывать только относительный путь »

я не справился, уж как я его (относительный путь) не подставлял. Подскажите, какого вида должна быть строка, чтобы я увидел результат содержащий уже и путь к файлу!?

Anonymоus 04-06-2012 15:47 1927836

Просто положите файл рядом со скриптом, и там, где указано "Set File=test.txt" - поставьте своё имя файла. Это и есть относительный путь, в отличии от абсолютного, когда путь полный, и начинается с указания диска.

Baranius 04-06-2012 16:37 1927881

Я имел в виду другое, как теперь с помощью Вашего скрипта обнаружить дубликаты в моём списке состоящим из трёх столбцов-полей
"1|путь к файлу|длительность" ?
Ведь Ваш скрипт я проверял на списке , состоящем только из одного столбца - "длительность"

Baranius 05-06-2012 13:50 1928459

Попробую ещё раз обратиться.
Ув. Anonymоus не сможете ли Вы подправить свой скрипт из 2 поста под список "test.txt" не с одним полем - "длительность", а с тремя полями вида:
"1|путь к файлу|длительность", чтобы я смог в результате увидеть дубликаты уже с их путями.
Благодарю.

Anonymоus 05-06-2012 19:17 1928701

Код:

@Echo Off
Set File=test.txt
rem Разбираем файл построчно
For /F "usebackq delims=" %%S In ("%File%") Do (
    rem Выделяем из строки длительность
    For /F "tokens=3 delims=^|" %%L In ("%%S") Do (
        rem Проводим поиск по файлу в поисках такой же длительности
        For /F "tokens=3 delims=: " %%C In ('Find /C "|%%L" "%File%"') Do (
            rem Раскидываем строки по разным спискам
            If "%%C"=="1" (
                Echo %%S>>"checked.txt"
            ) Else (
                Echo %%S>>"duplicated.txt"
            )
        )
    )
)

Все дубликаты пишет в "duplicated.txt", а не повторяющиеся строки в "checked.txt". Для вашего удобства я сделал вывод не только повторяющейся длительности, а строки целиком - включая путь.

Baranius 06-06-2012 00:34 1928979

Anonymоus! Безупречно.
Не только я, все пользователи AIMPa, будут благодарны Вам. Это ж сколько дискового пространства у каждого освободится! А в мировом масштабе? (скрипт использует уникальные свойства плейлиста AIMPa, для поиска дубликатов. Интересно - стучитесь).
Последние вопросы:
- нет ли ограничений на количество строк в файле "test.txt", ну, или его веса?
- нельзя ли вместо черного окна cmd.exe увидеть уставшее, но доброе лицо Anonymоusа, и вместо привычного текста "Нажмите.." прочитать "Налейте...", да, и ещё
- мы все можем пользоваться Вашим скриптом? (можно подумать, что это кого-то остановит. И всё же)
Спасибо!

Anonymоus 06-06-2012 01:45 1929024

Цитата:

Цитата Baranius
- нет ли ограничений на количество строк в файле "test.txt", ну, или его веса? »

Только по времени - чем больше список, тем медленней отрабатывает Find (каждую строку ищёт по всему файлу). Думаю, где-то до двухсот тысяч строк не должно возникать никаких затруднений. Если нужно обрабатывать очень большие списки, могу переделать скрипт с использование grep вместо find, он намного быстрее работает, но минус в том, что это стороняя утилита и по умолчанию отсутствует в windows.

Baranius 07-06-2012 00:12 1929726

Вложений: 3
Anonymоus, может Вам будут интересны результаты тестирования.
Собрал на старой машине (Barton 1,8 Мгц, память - 1Гб) ~15 000 файлов (70Гб весом). Из плейлиста подготовил "test.txt " - запустил Ваш скрипт поиска дублей. Комп загрузился на 100%, (процессы.jpg) и работал он ... 1час 40 минут. Стресс-тест, как говорится, но результат выдал.
И вот первый вывод: кол-во песен с равной до миллисекунды длительностью (судя по весу файла "! duplicated (1ч 40м) весь - 15 000.txt") почти равно половине всех песен (вторая строчка на скриншоте _кол-во дублей.jpg ). Не поверил, взял первую 1 000 строк из "test.txt ", потом первые 3 000, следом ещё 3 000 строк из середины файла (там, где длина песен "L=226s" самая распространённая) - результат тот же и неутешительный для меня - слишком много совпадений и искать именно дубли одинаковых песен среди такого кол-ва совпадений будет некомфортно. Так и вышло. Вот скрин (_dup-203сек.jpg) совпадений песен в диапазоне только одной секунды 203000 - 203999мс (3:23). Из 53 штук только 2 пары дублей (желтенькие).
Выводы - одного поля для сравнения, а тем более, поиска дубликатов мало (нужно чем-то подпирать, хоть тем же размером);
- время обработки растёт не пропорционально кол-ву обрабатываемых строк, очевидно Find не отбрасывает из рассмотрения 1 строку, после того, как переходит ко второй и т.д.;
- нашлись и неточности, присущие Find, о которых Вы говорили ранее - несколько сотен почему-то именно коротких файлов (L- 5тизначное) с цифрами в пути.
А про тесты синхронизации старого ПЛ с упорядочненными файлами на диске (умный поиск-сравнение в списках) отпишусь в родной теме.
Ещё раз, спасибо за поддержку и понимание.

Anonymоus 07-06-2012 03:03 1929790

Да, результаты интересные. Выходит, сочетание идентификации по длительности, плюс ошибки самого алгоритма поиска явно не дают требуемой точности. Сравнение одновременно с длительностью ещё и по размеру - это не совсем адекватная задача для чистого cmd, без применения внешних утилит, не тот инструмент.

Цитата:

Цитата Baranius
- время обработки растёт не пропорционально кол-ву обрабатываемых строк, очевидно Find не отбрасывает из рассмотрения 1 строку, после того, как переходит ко второй и т.д.; »

Так и есть, не отбрасывает. Каждая строка ищется по всему файлу каждый раз.

Увы, по итогам выходит, что практического применения данный скрипт не имеет.

Baranius 07-06-2012 12:22 1929969

Цитата:

Цитата Anonymоus
Увы, по итогам выходит, что практического применения данный скрипт не имеет. »

Неправда, Вы взгляните на благодарности. Уже кому-то это решение показалось полезным. И, наверняка найдется куча задач, где Ваш скрипт очень пригодится (отчет-сводка за день, неделю). Я же, например, с удовольствием теперь анализирую свою фонотеку по частям (у меня папки 2002, 2003...сейчас уже 2012). И работать мне с полученными данными прямо в AIMPe (см. выше-_dup-203сек.jpg) очень удобно, хотя есть куча программ для поиска дубликатов.
Спасибо!


Время: 08:59.

Время: 08:59.
© OSzone.net 2001-