Удалите последовательные строки в CSV с повторяющимися значениями в одном поле, но сохраните последнюю строку

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

... 1500,1533 1554,1678 1554,1703 1554,1728 1593,1766 ... 

Мне нужно удалить все эти дубликаты, кроме последнего, так что вывод для примера выше:

 ... 1500,1533 1554,1728 1593,1766 ... 

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

Я попробовал tac file.csv | sort -k1,1 -r -u -t, tac file.csv | sort -k1,1 -r -u -t,

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

3 Solutions collect form web for “Удалите последовательные строки в CSV с повторяющимися значениями в одном поле, но сохраните последнюю строку”

С sed :

 sed '$!N;/\(.*,\).*\n\1/!P;D' infile 

N означает, что в пространстве шаблонов всегда есть две последовательные строки, а sed P – первый из них, только если первое поле в этой строке не совпадает с первым полем во второй строке. Затем D удаляет первую строку из пространства шаблонов и перезапускает цикл.


Другой способ с gnu datamash (если ваш файл отсортирован, так как datamash требует отсортированного ввода):

 datamash -t ',' -g 1 last 2 <infile 

Это g объединяет ввод с разделителями по 1 -ому полю, распечатывая только last значение (из 2 го столбца) каждой группы.


Если ваш файл не отсортирован, datamash может сортировать его через -s :

 datamash -t ',' -s -g 1 last 2 <infile 

но это означает, что начальный порядок строк не будет сохранен. Так что это может не делать то, что вы хотите. В этом случае вы можете использовать sed / awk / perl т. Д. …

И альтернативный awk:

  awk -F, 'NR==1{old=$0;check=$1}NR>1 && $1 != check {print old}{old=$0;check=$1}END{print old}' knovice 1500,1533 1554,1728 1593,1766 

Вот еще один awk подход (спасибо @Glenn ):

  tac file | awk -F, 'awk -F, '!seen[$1]++' | tac 

-F, устанавливает разделитель. В awk действие по умолчанию, когда выражение принимает значение true, это печать текущей строки. !seen[$1] будет истинным, если первое поле не существует в рассматриваемом массиве. Однако, поскольку мы также создаем его с seen[$1]++ , это будет только ложным в первый раз, когда это видно. В результате будет напечатан только первый дубликат.

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

  • CSV-обработка файлов - удалите кавычки и замените разделитель запятой на вкладку
  • строка обновления на основе предыдущей строки
  • Быстрый способ удалить строку из чрезвычайно большого файла
  • Обертывание длинных ячеек в ЦС, чтобы держать их в одной колонке
  • Как оптимизировать скрипт с помощью NF и цикла for
  • CSV-файл + установить параметры и значения CSV в сценарии bash
  • Как отображать TSV (csv) в консоли, когда пустые ячейки пропущены: `column -t -s $ '\ t'`
  • Как изменить / упорядочить данные в файле с помощью Awk
  • awk, когда оба разделителя и кавычки используются для поля
  • объединить два файла csv на основе условия
  • Разбор текстового файла с разделителями в bash как аргументы команды
  • Linux и Unix - лучшая ОС в мире.