Как найти одинаковые строки в текстовом файле

Имеется два текстовых файла содержащие строки: file_0.txt и file_1.txt. Количество строк может быть разным. Длина строк может быть разной. Файлы содержат большое количество строк. Необходимо эффективно вывести в другой файл строки, которые содержатся одновременно в двух файлах.
Пример:
Содержимое файла file_0.txt:

file_0.txt

j43j72h531
b2x891ow52
rr35986z77
x77jm9lp7g
q0pprcp52yawc10
wh3h476m2u
e7h0cv6rh5
5l7i700939
l3ri0p8p2f
l1h14no300

Содержимое файла file_1.txt:

file_1.txt

l1h14no300
j2615a2e0y
815555v33h
q0pprcp52yawc10
2vhhh0ugxv
rc2jl8lhdl
79qn640321
b2x891ow52

Необходимое содержимое файла file_2.txt после работы программы/команды:

file_2.txt

b2x891ow52
q0pprcp52yawc10
l1h14no300

Я пытался это сделать с помощью CMD команды findstr но в выводе получал почему-то не все совпадающие строки, хотя их наличие я проверял вручную. На процессоре i5-8400 скорость сравнения 100’000 строк в одном и 100’000 в другом файле меня вполне устраивает: 10-15 секунд.
Подскажите команду CMD/PowerShell или программу, чтобы сделать задуманное.

This will print duplicate lines only, with counts:

sort FILE | uniq -cd

or, with GNU long options (on Linux):

sort FILE | uniq --count --repeated

on BSD and OSX you have to use grep to filter out unique lines:

sort FILE | uniq -c | grep -v '^ *1 '

For the given example, the result would be:

  3 123
  2 234

If you want to print counts for all lines including those that appear only once:

sort FILE | uniq -c

or, with GNU long options (on Linux):

sort FILE | uniq --count

For the given input, the output is:

  3 123
  2 234
  1 345

In order to sort the output with the most frequent lines on top, you can do the following (to get all results):

sort FILE | uniq -c | sort -nr

or, to get only duplicate lines, most frequent first:

sort FILE | uniq -cd | sort -nr

on OSX and BSD the final one becomes:

sort FILE | uniq -c | grep -v '^ *1 ' | sort -nr


Linux, Windows

Как найти все повторяющиеся и не повторяющиеся строки в файлах

  • 16.11.2022
  • 627
  • 0
  • 6
  • 6
  • 0

Как найти все повторяющиеся и не повторяющиеся строки в файлах

  • Содержание статьи
    • Вступление
    • В Linux
      • Ищем НЕ ПОВТОРЯЮЩИЕСЯ строки (уникальные)
      • Ищем ПОВТОРЯЮЩИЕСЯ строки (дубликаты)
    • Добавить комментарий

Вступление

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

В Linux

Ищем НЕ ПОВТОРЯЮЩИЕСЯ строки (уникальные)

Допустим у нас есть два текстовых файла:

Содержимое файла file1.txt

aaa
bbb
ccc
ddd
eee
fff
ggg

Содержимое файла file2.txt

bbb
aaa
ccc
eee
111
222
ddd
xxx

Для того, чтобы найти все уникальные строки в файле file1.txt (т.е. те строки, которые не содержатся в файле file2.txt) можно воспользоваться следующей командой:

cat file1.txt | grep -v -f file2.txt

Результат выполнения данной команды будет таким:

fff
ggg

Как мы видим в результате выполнения данной команды выводятся только те строки, которые уникальны в файле file1.txt и которых нет в файле file2.txt

Для того, чтобы найти все уникальные строки в файле file2.txt (т.е. те строки, которые не содержатся в файле file1.txt) можно воспользоваться следующей командой:

cat file2.txt | grep -v -f file1.txt

Результат выполнения данной команды будет таким:

111
222
xxx

Ищем ПОВТОРЯЮЩИЕСЯ строки (дубликаты)

Допустим у нас есть два текстовых файла:
Содержимое файла file1.txt

aaa
bbb
ccc
ddd
eee
fff
ggg

Содержимое файла file2.txt

bbb
aaa
ccc
eee
111
222
ddd
xxx

Для того, чтобы найти все повторяющиеся строки (дубликаты) в файлах file1.txt и file2.txt можно воспользоваться следующей командой:

cat file1.txt | grep -f file2.txt

Результат выполнения данной команды будет таким:

aaa
bbb
ccc
ddd
eee

Имеется база вида (Где есть повторяющиеся строки):

+Результат
+Ошибка
+Результат
+Результат
+Результат
+Ошибка
......

Нужно посчитать все повторяющиеся строки что расположены в текстовом файле и вывести отчет в Memo1. Результат должен получится в Memo1 такой:

+Результат - 4 раза
+Ошибка - 2 раза

То есть посчитать все одинаковые строки что есть в текстовом файле и статистику вывести в Memo1.

Предоставленный код работает быстро но вот при размерах файла в 600 мегабайт выдает сообщение о нехватке памяти. Ну это и понятно потому как мы все грузим в память.

procedure TForm1.Button1Click(Sender: TObject);
var
  TS: TStringList;
  s, OneWord: string;
  i, Cnt: integer;
begin
  TS := TStringList.Create;
  TS.Delimiter := '+';
  TS.LoadFromFile('baza.txt');
  s := TS.Text;
  TS.DelimitedText := s;

  if TS.Count = 0 then
  begin
    ShowMessage('Вообще ни одного слова нет!');
    Exit;
  end;

  TS.Sort;

  Memo1.Lines.Clear; // подготовим место для формирования отчёта

  // собственно подсчёт
  OneWord := TS.Strings[0];
  Cnt := 1;
  for i := 1 to TS.Count - 1 do
    if AnsiUpperCase(TS.Strings[i]) = AnsiUpperCase(OneWord) then
      inc(Cnt)
    else
    begin
      Memo1.Lines.Append(OneWord + '+' + InttoStr(Cnt));
      OneWord := TS.Strings[i];
      Cnt := 1;
    end;

  // для последнего слова в списке вывод результата
  Memo1.Lines.Append(OneWord + '+' + InttoStr(Cnt));

  FreeAndNil(TS); // освободим память
end;

Пробовала оформить код через AssignFile – чтение построчно но у меня тут ошибки. Помогите исправить ?

var
  TS: TStringList;
  s,st: string;
  i, Cnt: integer;
  f1: TextFile;
begin
  Memo1.Lines.Clear; // подготовим место для формирования отчёта

  // Открываем диалог выбора файла
  if not OpenDialog1.Execute then
    exit
  else
    AssignFile(f1, OpenDialog1.FileName);
  reset(f1);

  TS := TStringList.Create;
  TS.Delimiter := '+';
  s := TS.Text;
  TS.DelimitedText := s;
  TS.Sort;

  if TS.Count = 0 then
  begin
    ShowMessage('Вообще ни одного слова нет!');
    exit;
  end;

  While not EOF(f1) do
  begin
    // Что бы программа не подвисала
    Application.ProcessMessages();
    readln(f1, st);
    TS.Add(st);

    // собственно подсчёт
    st := TS.Strings[0];
    Cnt := 1;
    for i := 1 to TS.Count - 1 do
      if AnsiUpperCase(TS.Strings[i]) = AnsiUpperCase(st) then
        inc(Cnt)
      else
      begin
        Memo1.Lines.Append(st + '-' + InttoStr(Cnt));
        st := TS.Strings[i];
        Cnt := 1;
      end;

    // для последнего слова в списке вывод результата
    Memo1.Lines.Append(st + '-' + InttoStr(Cnt));

    FreeAndNil(TS); // освободим память

  end;

  TS.Free;
  CloseFile(f1);

end;

Вы когда-нибудь сталкивались с текстовыми файлами с повторяющимися строками и повторяющимися словами? Возможно, вы регулярно работаете с выводом команд и хотите отфильтровать их для отдельных строк. Когда дело доходит до текстовых файлов и удаления избыточных данных в Linux, команда uniq – ваш лучший выбор.

В этой статье мы подробно обсудим команду uniq, а также подробное руководство о том, как использовать команду для удаления повторяющихся строк из текстового файла.

Команда uniq в Linux используется для отображения идентичных строк в текстовом файле. Эта команда может быть полезна, если вы хотите удалить повторяющиеся слова или строки из текстового файла. Поскольку команда uniq сопоставляет соседние строки для поиска избыточных копий, она работает только с отсортированными текстовыми файлами.

К счастью, вы можете передать команду сортировки по конвейеру с помощью uniq, чтобы организовать текстовый файл таким образом, чтобы это было совместимо с командой. Помимо отображения повторяющихся строк, команда uniq также может подсчитывать появление повторяющихся строк в текстовом файле.

Как использовать команду uniq

Существуют различные параметры и флаги, которые вы можете использовать с uniq. Некоторые из них являются базовыми и выполняют простые операции, такие как печать повторяющихся строк, в то время как другие предназначены для опытных пользователей, которые часто работают с текстовыми файлами в Linux.

Базовый синтаксис

Базовый синтаксис команды uniq:

 uniq option input output

… где option – это флаг, используемый для вызова определенных методов команды, input – это текстовый файл для обработки, а output – это путь к файлу, в котором будет храниться вывод.

Выходной аргумент является необязательным и может быть пропущен. Если пользователь не указывает входной файл, uniq берет данные из стандартного вывода в качестве входных. Это позволяет пользователю передавать uniq по конвейеру с другими командами Linux .

Пример текстового файла

Мы будем использовать текстовый файл duplicate.txt в качестве входных данных для команды.

 127.0.0.1 TCP
127.0.0.1 UDP
Do catch this
DO CATCH THIS
Don't match this
Don't catch this
This is a text file.
This is a text file.
THIS IS A TEXT FILE.
Unique lines are really rare.

Обратите внимание, что мы уже отсортировали этот текстовый файл с помощью команды sort . Если вы работаете с другим текстовым файлом, вы можете отсортировать его с помощью следующей команды:

 sort filename.txt > sorted.txt

Удалить повторяющиеся линии

Основное использование uniq – удаление повторяющихся строк из ввода и печать уникального вывода.

 uniq duplicate.txt

Выход:

Обратите внимание, что система не отображает второе вхождение строки. Это текстовый файл . Кроме того, вышеупомянутая команда печатает только уникальные строки в файле и не влияет на содержимое исходного текстового файла.

Подсчет повторяющихся строк

Чтобы вывести количество повторяющихся строк в текстовом файле, используйте флаг -c с командой по умолчанию.

 uniq -c duplicate.txt

Выход:

Система отображает количество строк в текстовом файле. Вы можете видеть, что строка This is a text file встречается в файле два раза. По умолчанию команда uniq чувствительна к регистру.

Печатать только повторяющиеся строки

Чтобы печатать только повторяющиеся строки из текстового файла, используйте флаг -D . -D означает Дубликат .

 uniq -D duplicate.txt

Система отобразит вывод следующим образом.

 This is a text file.
This is a text file.

Пропуск полей при проверке дубликатов

Если вы хотите пропустить определенное количество полей при сопоставлении строк, вы можете использовать флаг -f с командой. -F означает поле .

Рассмотрим следующий текстовый файл fields.txt .

 192.168.0.1 TCP
127.0.0.1 TCP
354.231.1.1 TCP
Linux FS
Windows FS
macOS FS

Чтобы пропустить первое поле:

 uniq -f 1 fields.txt

Выход:

 192.168.0.1 TCP
Linux FS

Вышеупомянутая команда пропустила первое поле (IP-адреса и имена ОС) и сопоставила второе слово (TCP и FS). Затем он отображал первое вхождение каждого совпадения в качестве вывода.

Игнорировать символы при сравнении

Как и при пропуске полей, вы также можете пропускать символы. Флаг -s позволяет указать количество символов, которые следует пропускать при сопоставлении повторяющихся строк. Эта функция помогает, когда данные, с которыми вы работаете, представлены в виде следующего списка:

 1. First
2. Second
3. Second
4. Second
5. Third
6. Third
7. Fourth
8. Fifth

Чтобы игнорировать первые два символа (нумерацию списков) в файле list.txt :

 uniq -s 2 list.txt

Выход:

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

Проверьте количество первых N символов на наличие дубликатов

Флаг -w позволяет проверять на наличие дубликатов только фиксированное количество символов. Например:

 uniq -w 2 duplicate.txt

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

Выход:

Удалить чувствительность к регистру

Как упоминалось выше, uniq чувствителен к регистру при сопоставлении строк в файле. Чтобы игнорировать регистр символов, используйте параметр -i с командой.

 uniq -i duplicate.txt

Вы увидите следующий результат.

Обратите внимание, что в выводе выше uniq не отображал строки DO CATCH THIS и THIS IS A TEXT FILE .

Отправить вывод в файл

Чтобы отправить вывод команды uniq в файл, вы можете использовать символ перенаправления вывода ( > ) следующим образом:

 uniq -i duplicate.txt > otherfile.txt

При отправке вывода в текстовый файл система не отображает вывод команды. Вы можете проверить содержимое нового файла с помощью команды cat .

 cat otherfile.txt

Вы также можете использовать другие способы отправки вывода командной строки в файл в Linux .

Анализ повторяющихся данных с помощью uniq

Большую часть времени при управлении серверами Linux вы будете либо работать на терминале, либо редактировать текстовые файлы. Следовательно, знание того, как удалить избыточные копии строк в текстовом файле, может стать большим подспорьем для вашего набора навыков работы с Linux.

Работа с текстовыми файлами может быть неприятной, если вы не знаете, как фильтровать и сортировать текст в файле. Чтобы упростить вашу работу, в Linux есть несколько команд редактирования текста, таких как sed и awk, которые позволяют эффективно работать с текстовыми файлами и выводами командной строки.

Добавить комментарий