uniq a csv файл, игнорирующий столбец, возможно, awk?

Учитывая этот файл (аннотации не являются частью файла, но составляют часть объяснения) …

x,a,001,b,c,d,y x,a,002,b,c,e,yy x,bb,003,b,d,e,y x,c,004,b,d,e,y x,c,005,b,d,e,y # nb - dupe of row 4 x,dd,006,b,d,e,y x,c,007,b,d,e,y # nb - dupe of row 4 and 5 x,dd,008,b,d,f,y x,dd,009,b,d,e,y # nb - dupe of row 6 x,e,010,b,d,f,y 

… Я хотел бы получить следующий результат:

 x,a,001,b,c,d,y x,a,002,b,c,e,yy x,bb,003,b,d,e,y x,c,004,b,d,e,y x,dd,006,b,d,e,y x,dd,008,b,d,f,y x,e,010,b,d,f,y 

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

Но я действительно борется, чтобы придумать что-то, что сделало бы это. Я хотел бы получить возможность узнать об утилитах обработки текста Linux.

Производительность. Файлы не выглядят более чем 1 МБ, и есть только 1 файл в день.

Цель: Debian GNU / Linux 7 amd64, 256MB / Xeon.

Edit: tweaked example, поскольку поля не являются фиксированной шириной, а решение с участием uniq --skip-chars=n не будет работать, насколько я могу судить.

4 Solutions collect form web for “uniq a csv файл, игнорирующий столбец, возможно, awk?”

С awk вы можете сделать:

 awk -F, -vOFS=, '{l=$0; $3=""}; ! ($0 in seen) {print l; seen[$0]}' 

Самый простой способ :

 sort -u -t, -k1,2 -k4 
  • -u : выводит только первую строку равных
  • -t, использовать запятую как разделитель полей
  • -k1,2 -k4 : сортировать только по полям 1,2 и 4, а остальные

Другой вариант – переупорядочить данные с помощью sed (обратите внимание на вариант GNU -r ) с обеих сторон – для этого требуется, чтобы записи были в основном фиксированной длиной, иначе он будет терпеть неудачу (и только едва заметно):

 sed -r 's/^([^,]+,[^,]+)(,[^,]+)(.*)$/\1\3\2/' \ | sort \ | uniq -w 12 \ | sed -r 's/^([^,]+,[^,]+)(.*)(,[^,]+)$/\1\3\2/' 

Возможно, вы захотите добавить еще один sort в конце, чтобы заказать его по номерам, если хотите (используйте опцию -k для выбора в соответствии с тем, что должно выполняться сортировка, т.е. что-то вроде sed -k3 -t, )

В Perl вы можете, например, использовать части, на которых вы хотите выбрать уникальность в качестве ключей в хеше (значения полных строк) и вставить в хэш только в том случае, если ключ еще не определен. Разумеется, это будет гораздо более гибким, чем использование sed (или awk ), но также и больше написания (я далек от Perl Guru, поэтому очень вероятно, что это можно сделать гораздо более изящным способом), см. Другие ответы для Perl как Perl-решения):

 #!/usr/bin/perl use strict; my %lines; while (<>) { (my $k1, my $v, my $k2) = /^([^,]+,[^,]+,)([^,]+)(,.*)$/; my $k = $k1 . $k2; if (!exists($lines{$k})) { $lines{$k} = $_; } } for my $k (sort(keys(%lines))) { print $lines{$k}; } 

Способ сделать это с помощью awk | sort | uniq | awk awk | sort | uniq | awk awk | sort | uniq | awk :

 awk -F, '{a=$1;$1=$3;$3=a;print}' file | sort -k 2 | uniq -f 1 | awk -v OFS=',' '{a=$1;$1=$3;$3=a;print}' 

Простейшим способом Perl будет:

 perl -F"," -ane '$a=join(",",@F[0,1,3 .. $#F]); print unless $k{$a}; $k{$a}++' file 

Параметр -a разбивает поля на @F и -F"," устанавливает разделитель полей в. -n означает запустить сценарий, заданный -e в каждой строке входного файла.

Идея состоит в том, чтобы взять срез массива (элементы 0,1 и 3 до конца массива), объединить их в строку ( $a ) и использовать эту строку как ссылку хеша (ассоциативный массив). Затем вы печатаете каждую строку только в том случае, если хеш-ключ не был замечен раньше.

  • Элемент сортировки POSIX Awk
  • Как работает awk?! ++?
  • sort: write failed | Сломанная труба
  • Выполнение команды для каждого файла в папке в случайном порядке
  • Как создать скрипт с обратным действием
  • Ограничение размера файла превышено в bash
  • Перечислите дни рождения в том порядке, в котором они придут с сегодняшнего дня
  • Команда сортировки в нескольких полях
  • Как распечатать пять самых высоких чисел из столбца?
  • Насколько разумны утилиты unix?
  • Как сделать обратный вывод, который уже передан из команд сортировки и вырезания
  • Linux и Unix - лучшая ОС в мире.