Подтвердить что ты не робот

Удаление повторяющихся строк без сортировки

У меня есть утилита script в Python:

#!/usr/bin/env python
import sys
unique_lines = []
duplicate_lines = []
for line in sys.stdin:
  if line in unique_lines:
    duplicate_lines.append(line)
  else:
    unique_lines.append(line)
    sys.stdout.write(line)
# optionally do something with duplicate_lines

Эта простая функциональность (uniq без необходимости сортировки первого, стабильного порядка) должна быть доступна как простая утилита UNIX, не так ли? Может быть, комбинация фильтров в трубе?

Причина для запроса: нужна эта функция в системе, на которой я не могу выполнить python извне

4b9b3361

Ответ 1

Блог UNIX Bash Scripting предлагает:

awk '!x[$0]++'

Эта команда сообщает awk, какие строки печатать. Переменная $0 содержит все содержимое строки, а квадратные скобки - это доступ к массиву. Таким образом, для каждой строки файла узел массива x увеличивается и строка выводится, если ранее содержимое этого узла не было (!).

Ответ 2

Поздний ответ - я просто столкнулся с дубликатом этого, но, возможно, стоит добавить...

Принцип ответа @1_CR может быть написан более сжато, используя cat -n вместо awk для добавления номеров строк:

cat -n file_name | sort -uk2 | sort -nk1 | cut -f2-
  • Используйте cat -n для добавления номеров строк
  • Использовать sort -u удалить повторяющиеся данные
  • Используйте sort -n для сортировки по добавленному номеру
  • Используйте cut для удаления нумерации строк

Ответ 3

Решение Майкла Хоффмана выше короткое и сладкое. Для более крупных файлов подход преобразования Шварца, включающий добавление поля индекса с использованием awk, сопровождаемого несколькими раундами сортировки и uniq, требует меньшего объема служебных данных. Следующий фрагмент работает в bash

awk '{print(NR"\t"$0)}' file_name | sort -t$'\t' -k2,2 | uniq --skip-fields 1 | sort -k1,1 -t$'\t' | cut -f2 -d$'\t'

Ответ 4

Спасибо 1_CR! Мне нужно было "uniq -u" (удалить дубликаты целиком), а не uniq (оставить 1 копию дубликатов). Решения awk и perl действительно не могут быть изменены, чтобы сделать это, ваши возможности! Возможно, мне также понадобилось более низкое использование памяти, так как я буду uniq'ing, как 100 000 000 строк 8-). На всякий случай, если кому-то это понадобится, я просто поставлю "-u" в команде uniq команды:

awk '{print(NR"\t"$0)}' file_name | sort -t$'\t' -k2,2 | uniq -u --skip-fields 1 | sort -k1,1 -t$'\t' | cut -f2 -d$'\t'

Ответ 5

Чтобы удалить дубликат из 2 файлов:

awk '!a[$0]++' file1.csv file2.csv

Ответ 6

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

awk '{
  if ($0 != PREVLINE) print $0;
  PREVLINE=$0;
}'

Ответ 8

Теперь вы можете проверить этот небольшой инструмент, написанный на Rust: uq.

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