Удалить дублирующиеся строки из текстового файла?

Как Leigh Caldwell заявил, оптимизатор запросов может произвести различные планы запросов на основе того, что функционально похоже на тот же SQL-оператор. Для дополнительных материалов для чтения на этом взгляните на следующие два postings:-

блога Одна регистрация от Команды Оптимизатора Oracle

Другая регистрация из блога

"Структурированных данных", я надеюсь, что Вы находите это интересным.

8
задан Mogsdad 14 April 2016 в 19:37
поделиться

4 ответа

Это должно работать (и будет копироваться с большими файлами).

Обратите внимание, что при этом удаляются только дубликаты последовательных строк, то есть

a
b
b
c
b
d

в итоге будет

a
b
c
b
d

Если вы не хотите нигде дубликатов, вам нужно сохранить набор строк, которые вы уже видели.

using System;
using System.IO;

class DeDuper
{
    static void Main(string[] args)
    {
        if (args.Length != 2)
        {
            Console.WriteLine("Usage: DeDuper <input file> <output file>");
            return;
        }
        using (TextReader reader = File.OpenText(args[0]))
        using (TextWriter writer = File.CreateText(args[1]))
        {
            string currentLine;
            string lastLine = null;

            while ((currentLine = reader.ReadLine()) != null)
            {
                if (currentLine != lastLine)
                {
                    writer.WriteLine(currentLine);
                    lastLine = currentLine;
                }
            }
        }
    }
}

Обратите внимание, что это предполагает ] Encoding.UTF8 , и вы хотите использовать файлы. Однако это легко обобщить как метод:

static void CopyLinesRemovingConsecutiveDupes
    (TextReader reader, TextWriter writer)
{
    string currentLine;
    string lastLine = null;

    while ((currentLine = reader.ReadLine()) != null)
    {
        if (currentLine != lastLine)
        {
            writer.WriteLine(currentLine);
            lastLine = currentLine;
        }
    }
}

(Обратите внимание, что это ничего не закрывает - вызывающий должен это делать.)

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

static void CopyLinesRemovingAllDupes(TextReader reader, TextWriter writer)
{
    string currentLine;
    HashSet<string> previousLines = new HashSet<string>();

    while ((currentLine = reader.ReadLine()) != null)
    {
        // Add returns true if it was actually added,
        // false if it was already there
        if (previousLines.Add(currentLine))
        {
            writer.WriteLine(currentLine);
        }
    }
}
20
ответ дан 5 December 2019 в 04:30
поделиться

Для маленьких файлов:

string[] lines = File.ReadAllLines("filename.txt");
File.WriteAllLines("filename.txt", lines.Distinct().ToArray());
33
ответ дан 5 December 2019 в 04:30
поделиться

Долгое время файл (и непоследовательные дублирования), я бы скопировал файлы построчно, построив таблицу поиска // хеш-позиции по ходу дела.

При копировании каждой строки проверяйте хешированное значение, если есть коллизия, дважды проверьте, что строка такая же и перейти к следующей. (

Только для довольно больших файлов.

3
ответ дан 5 December 2019 в 04:30
поделиться

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

    var sr = new StreamReader(File.OpenRead(@"C:\Temp\in.txt"));
    var sw = new StreamWriter(File.OpenWrite(@"C:\Temp\out.txt"));
    var lines = new HashSet<int>();
    while (!sr.EndOfStream)
    {
        string line = sr.ReadLine();
        int hc = line.GetHashCode();
        if(lines.Contains(hc))
            continue;

        lines.Add(hc);
        sw.WriteLine(line);
    }
    sw.Flush();
    sw.Close();
    sr.Close();
3
ответ дан 5 December 2019 в 04:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: