Инструмент unix для удаления повторяющихся строк из файла

У меня есть инструмент, который генерирует тесты и прогнозирует вывод. Идея состоит в том, что если у меня есть сбой, я могу сравнить предсказание с фактическим выходом и посмотреть, где они расходятся. Проблема в том, что фактический вывод содержит несколько строк дважды, что смущает diff. Я хочу удалить дубликаты, чтобы я мог легко сравнивать их. В принципе, что-то вроде sort -u, но без сортировки.

Есть ли какой-нибудь инструмент командной строки unix, который может это сделать?

Ответ 1

uniq (1)

СИНТАКСИС

uniq [OPTION]... [INPUT [OUTPUT]]

ОПИСАНИЕ

Отменить все, кроме одного из последовательных идентичных строк, от INPUT (или стандартного ввода), записать в OUTPUT (или стандартный вывод).

Или, если вы хотите удалить не соседние повторяющиеся строки, этот фрагмент perl сделает это:

while(<>) {
    print $_ if (!$seen{$_});
    $seen{$_}=1;
}

Ответ 2

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

cat textfile | perl -ne '$H{$_}++ or print'

Ответ 3

Если вы заинтересованы в удалении соседних повторяющихся строк, используйте uniq.

Если вы хотите удалить все повторяющиеся строки, а не только соседние, то это сложнее.

Ответ 4

Вот что я придумал, пока я ждал ответа здесь (хотя первый (и принятый) ответ пришел примерно через 2 минуты). Я использовал эту подстановку в VIM:

%s/^\(.*\)\n\1$/\1/

Это означает: найдите строки, где после новой строки мы имеем то же, что и раньше, и заменим их только тем, что мы зафиксировали в первой строке.

uniq определенно проще.

Ответ 5

Вот реализация awk, если в среде нет/разрешить perl (еще не видели)! PS: Если имеется более одной повторяющейся строки, это печатает повторяющиеся выходы.

awk '{

# Cut out the key on which duplicates are to be determined.
key = substr($0,2,14)

#If the key is not seen before, store in array,else print
if ( ! s[key] )
    s[key] = 1;
else
    print key;
}'