Удалите соседние дубликаты, сохраняя порядок


11

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

Например, я хочу повернуть левую сторону к правой стороне:

Golgb1    Golgb1    
Golgb1    Akna
Golgb1    Spata20
Golgb1    Golgb1
Golgb1    Akna
Akna
Akna
Akna
Spata20
Spata20
Spata20
Golgb1
Golgb1
Golgb1
Akna
Akna
Akna

Это то, что я использовал: perl -ne 'print if ++$k{$_}==1' file.txt > file2.txt однако, этот метод держит только одного представителя слева (т.е. Golb1 и Akna не повторяются).

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

Ответы:


23

uniq сделаю это для вас:

$ uniq inputfile
Golgb1
Akna
Spata20
Golgb1
Akna

2
вау это было смущающе легко! Спасибо!
Возраст87

@ Age87 Unix великолепен! Это работает только потому, что вы ожидаете, что дубликаты уже соседние (или не хотите удалять несмежные). Обычно рекомендуется использоватьsort | uniq
jpaugh

1
Или более кратко, sort -u(:
DopeGhoti


6

Попробуйте это - сохранить предыдущую строку и сравнить с текущей строкой

$ perl -ne 'print if $p ne $_; $p=$_' ip.txt
Golgb1
Akna
Spata20
Golgb1
Akna

Вы тоже пометили uniq- пробовали?

$ uniq ip.txt
Golgb1
Akna
Spata20
Golgb1
Akna

1

С помощью sed это можно сделать следующим образом:

sed -e '$!N;/^\(.*\)\n\1$/!P;D' input_file

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

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

perl -0777pe 's//$1/ while /^(.*\n)\1+/gm' input_file

0

Вопрос о разрешении Ракеша Шармы.

Что делать, если у вас есть входной файл, такой как:

-126.1 48.206
-126.106 48.21
-126.11 48.212
-126.114 48.214
-126.116 48.216
-126.118 48.216
-126.128 48.222
-126.136 48.226

И вы хотите, чтобы выходной файл был:

-126.1 48.206
-126.106 48.21
-126.11 48.212
-126.114 48.214
-126.116 48.216
-126.128 48.222
-126.136 48.226

Обратите внимание на отсутствие:

-126.118 48.216

Я знаю, что команда, которую я хочу, похожа на ваше решение:

sed -e '$!N;/^\(.*\)\n\1$/!P;D' input_file

Невозможно изменить его правильно, чтобы распечатать оба столбца, и сортировать его можно только особым образом со значениями столбца 2. Какие-нибудь советы?


sed -e '$!N' -e '/.*\.\([0-9]*\)\n.*\.\1$/!{P;D;}' -e 's/\n.*//;s/^/\n/;D' удалит последующие повторяющиеся элементы. Примечание: Для этого требуется GNU sed. Для POSIXповедения необходимо небольшое изменение.
Ракеш Шарма
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.