Как удалить частичные повторяющиеся строки с помощью AWK?

У меня есть файлы с такими повторяющимися строками, где отличается только последнее поле:

OST,0202000070,01-AUG-09,002735,6,0,0202000068,4520688,-1,0,0,0,0,0,55
ONE,0208076826,01-AUG-09,002332,316,3481.055935,0204330827,29150,200,0,0,0,0,0,5
ONE,0208076826,01-AUG-09,002332,316,3481.055935,0204330827,29150,200,0,0,0,0,0,55
OST,0202000068,01-AUG-09,003019,6,0,0202000071,4520690,-1,0,0,0,0,0,55

Мне нужно удалить первое вхождение строки и оставить второе.

Я пробовал:

awk '!x[$0]++ {getline; print $0}' file.csv

но он не работает должным образом, так как также удаляет не повторяющиеся строки.


person zedascouves    schedule 19.10.2009    source источник
comment
Ваши (близкие) дубликаты всегда рядом или они могут быть перемежены?   -  person Dennis Williamson    schedule 19.10.2009
comment
Они всегда смежные, так как уже являются результатом другой awk-операции.   -  person zedascouves    schedule 20.10.2009


Ответы (3)


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

#!/bin/awk -f
{
    s = substr($0, 0, match($0, /,[^,]*$/))
    if (s != prev) {
        print prev0
    }
    prev = s
    prev0 = $0
} 
END {
    print $0
}

Редактировать: Сценарий изменен таким образом, что он печатает последний в группе почти дубликатов (не требуется tac).

person Dennis Williamson    schedule 19.10.2009

В качестве общей стратегии (я не очень хорошо разбираюсь в AWK, несмотря на то, что посещаю занятия с Ахо), вы можете попробовать:

  1. Объедините все поля, кроме последнего.
  2. Используйте эту строку как ключ к хешу.
  3. Сохраните всю строку как значение хеша.
  4. Когда вы обработаете все строки, выполните цикл по хешу, распечатав значения.

Это не специфично для AWK, и я не могу легко предоставить какой-либо пример кода, но это то, что я бы попробовал в первую очередь.

person Willi Ballenthin    schedule 19.10.2009

person    schedule
comment
Здесь нужна звездочка после закрывающей квадратной скобки, чтобы соответствовать правильной подстроке. Кроме того, он идентичен awk '!x[substr($0, 1,16)]++ ' file.csv. Они оба страдают тем, что печатают первый из набора почти дубликатов, а не последний. - person Ewan Todd; 19.10.2009
comment
Идентичен этим данным обучения, то есть - person Ewan Todd; 19.10.2009
comment
Спасибо за исправление и хорошее понимание требований ОП. - person Steven Huwig; 19.10.2009
comment
Вы можете заставить это работать правильно, поместив его между вызовами tac, например. tac | script.awk file.txt | tac. Если вам посчастливилось иметь tac, конечно. :) - person Steven Huwig; 19.10.2009
comment
я имел в виду tac | script.awk | tac file.txt - person Steven Huwig; 19.10.2009
comment
tac-файл.csv|script.awk | так - person Ewan Todd; 19.10.2009
comment
Хорошее решение! Может быть объединен с решением Денниса в случае, который он определил. - person Ewan Todd; 19.10.2009