Как проверить на дубли огромное количество строк?

  • Автор темы Автор темы backoff
  • Дата начала Дата начала

backoff

Client
Регистрация
20.04.2015
Сообщения
6 386
Реакции
6 671
Баллы
113
Приветствую.

Подскажите, может кто сталкивался. Стоит задача проверить на дубли кучу строк. Как это сделать максимально удобно и качественно?
Речь идет о 10-20 млн строк


В ходе беседы я использовал следующее решение:

Как пользоваться:
- передать батнику файл аргументом (берем свой текстовый файл и просто пересовываем его мышкой на smf_sortcleaner.bat в проводнике windows), все остальное он сам сделает и создаст в папке с собой два файла, очищенный и повторы. А если просто запустить скрипт, без аргументов в смысле, то он обработает все .txt в папке с собой.

Требует для работы .net framework 2.
Исходный код открыт, можете переписывать под себя хоть в блокноте.

открытый код *.bat файла
Код:
Развернуть Свернуть Копировать
/*
@echo off && cls
set WinDirNet=%WinDir%\Microsoft.NET\Framework
IF EXIST "%WinDirNet%\v2.0.50727\csc.exe" set csc="%WinDirNet%\v2.0.50727\csc.exe"
IF EXIST "%WinDirNet%\v3.5\csc.exe" set csc="%WinDirNet%\v3.5\csc.exe"
IF EXIST "%WinDirNet%\v4.0.30319\csc.exe" set csc="%WinDirNet%\v4.0.30319\csc.exe"
%csc% /nologo /out:"%~0.exe" %0
"%~0.exe" %1
del "%~0.exe"
exit
*/

//14 mar 2015 @ 13:29
//metaspamer.blogspot.com

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace spicemustflow_sortcleaner
{
    class Program
    {
        static string GetFilename(string nameWithoutExtension, bool uniq)
        {
            int n = 1;
            string outputFile = string.Empty;
            while (true)
            {
                outputFile = string.Format("{0}_{1}{2}.txt",
                    nameWithoutExtension, uniq ? "uniques" : "duplicates",
                    n > 1 ? n.ToString() : string.Empty);
                if (File.Exists(outputFile)) n++;
                else break;
            }
            return outputFile;
        }

        static void Main(string[] args)
        {
            string path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\";
            string[] filelist = null;
            if (args.Length == 0) filelist = Directory.GetFiles(path, "*.txt", SearchOption.TopDirectoryOnly);
            else filelist = args;

            foreach (string filename in filelist)
            {
                Encoding enc = Encoding.Default;
                using (FileStream fs = File.OpenRead(filename))
                {
                    byte[] data = new byte[3];
                    while (fs.Read(data, 0, data.Length) > 0)
                        if (data[0] == 0xef && data[1] == 0xbb && data[2] == 0xbf)
                        {
                            enc = Encoding.UTF8;
                            break;
                        }
                        else
                        {
                            enc = Encoding.GetEncoding(1251);
                            break;
                        }
                }

                Console.Write("loading {0}..\n", filename);
                string[] input = File.ReadAllLines(filename, enc);
                if (input.Length > 0)
                {
                    Console.Write("sorting..\n");
                    Array.Sort(input);
                    List<string> uniques = new List<string>();
                    List<string> duplicates = new List<string>();
                    Console.Write("deleting duplicates..\n");
                    uniques.Add(input[0]);
                    for (int i = 1; i < input.Length; i++)
                        if (input[i] != input[i - 1])
                            uniques.Add(input[i]);
                        else
                            duplicates.Add(input[i]);

                    Console.Write("\nsaving..\n");
                    File.WriteAllLines(path + GetFilename(Path.GetFileNameWithoutExtension(filename), true), uniques.ToArray(), enc);
                    File.WriteAllLines(path + GetFilename(Path.GetFileNameWithoutExtension(filename), false), duplicates.ToArray(), enc);
                    Console.Write("\n\n");
                }
            }
        }
    }
}
 

Вложения

Последнее редактирование:
Приветствую.

Подскажите, может кто сталкивался. Стоит задача проверить на дубли кучу строк. Как это сделать максимально удобно и качественно?
Речь идет о 10-20 млн строк

спокойно удаляет дубли в файла по несколько гиг
главное место на диске должно быть
 

Вложения

52aY68wU4zVNl2.jpg


может чето не то делаю, но файл на 19мб (для теста) сортировал или дубли удалял 300 сек, после чего остановил.
как прогой пользоваться?


нашел как пользоваться...
только я просил удаление дублей, мне сортировка не нужна по алфавиту, я так понимаю изза этого прога тратит много времени именно на сортировку.
такое не подходит(
 
  • Оценить
Реакции: TIIGR и Gulid
  • Оценить
Реакции: backoff
ну и остальной софт можно юзать из этого поста.
огонь, батник просто крут, сортировка не нужна, но хрен с ней, если на это время не уходит )

UPD
хотя время на сортировку все-таки уходит, несколько секунд в зависимости от файла.

А можно сортировку отключить? Если да, то как?
 
  • Оценить
Реакции: TIIGR и Gulid
Думаю что нет, сам автор пишет:
Тут конечно есть недостаток (или достоинство) - результат получается отсортированный по алфавиту
 
Думаю что нет, сам автор пишет:
а почему нет, открывая батник там C# переписывайте по своему желанию, я уже не помню в какой ветке давно уже этот батник на форум кидал
 
Буду честным, я со своими слабыми знаниями кода заглянул в батник. Увидел, что там основной процесс в этом блоке:
C#:
Развернуть Свернуть Копировать
                   Array.Sort(input);
                    List<string> uniques = new List<string>();
                    List<string> duplicates = new List<string>();
                    Console.Write("deleting duplicates..\n");
                    uniques.Add(input[0]);
                    for (int i = 1; i < input.Length; i++)
                        if (input[i] != input[i - 1])
                            uniques.Add(input[i]);
                        else
                            duplicates.Add(input[i]);
Попробовал поначалу удалить строку сортировки:
И увидел, что после этого удаление дублей перестало работать. Так как именно на сортировке заточен алгоритм. Ведь после нее дубли сортируются подряд, и алгоритм сравнивает строку с предыдущей, не равна ли она ей:
C#:
Развернуть Свернуть Копировать
if (input[i] != input[i - 1])
Нет соритровки == нет поиска дублей.
Слышал, что в новых NET.Framework за последний ~год появлялись менее ресурсо-зависимые методы для удаления дублей, но опять же с моим уровнем не перенести их в батник.
 
Последнее редактирование:
Sort64.exe
Если оперативки достаточно, 26 гига дубли+ сортировка 2.5-3 минуты

Если оперативки куда меньше чем размер файла sort64lm

Для удаления из первого файла те что присуствуют в другом(их) третья тулза. В этом плане по скорости о объему мало что посоревнуеться.

http://downloads.unifiedlm.com/uploads/ulm_utils_3.zip
 

Кто просматривает тему: (Всего: 0, Пользователи: 0, Гости: 0)