CSV Фильтрация столбца со смешанными типами данных - PullRequest
0 голосов
/ 30 мая 2020

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

Когда я запускаю:

awk -F ',' '!seen[$4]++' oldfile.csv > newfile.csv

на

71523180,PRASAD  JAMES ANAND, ,#3 ALEX BOYD LINK HILLSBORO
71523190,PRASAD  SHAKUNPALA, ,#3 ALEX BOYD LINK HILLSBORO
71523200,PRASAD  BOBBY UMENDRA, ,#3 ALEX BOYD LINK HILLSBORO

, он возвращает то, что я хочу:

71523180,PRASAD  JAMES ANAND, ,#3 ALEX BOYD LINK HILLSBORO

Но когда я запускаю это строка кода на

71508050,"HUNT,  RICHARD F", ,1009 # B FATHOM DR
71508060,"HUNT,  RICHARD F", ,1009 # B FATHOM DR
71561950,"HUNT,  RICHARD F", ,1009 # B FATHOM DR
71562840,"HUNT,  RICHARD F", ,1009 # B FATHOM DR

удаляет все эти записи.

Что делать? Спасибо


ПОСЛЕДУЮЩИЕ УСЛОВИЯ

Использование perl, похоже, работает, но дает небольшую ошибку. Это проблема?

$ perl -w -MText::CSV_XS=csv -e &apos;csv(in => \*STDIN, filter => { 4 => sub { ! $seen{$_}++ }})&apos; < combined4.csv > combined6.csv
Name "main::seen" used only once: possible typo at -e line 1.

Ответы [ 3 ]

1 голос
/ 30 мая 2020

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

Пример perl однострочный с использованием модуля Text::CSV_XS (установка через диспетчер пакетов вашей ОС или любимый клиент CPAN):

$ perl -MText::CSV_XS=csv -e 'csv(in => \*STDIN, filter => { 4 => sub { ! $seen{$_}++ }})' < input.csv
71508050,"HUNT,  RICHARD F"," ","1009 # B FATHOM DR"
0 голосов
/ 30 мая 2020

используя Miller (https://github.com/johnkerl/miller) в этом CSV

71523180,PRASAD  JAMES ANAND, ,#3 ALEX BOYD LINK HILLSBORO
71523190,PRASAD  SHAKUNPALA, ,#3 ALEX BOYD LINK HILLSBORO
71523200,PRASAD  BOBBY UMENDRA, ,#3 ALEX BOYD LINK HILLSBORO
71508050,"HUNT,  RICHARD F", ,1009 # B FATHOM DR
71508060,"HUNT,  RICHARD F", ,1009 # B FATHOM DR
71561950,"HUNT,  RICHARD F", ,1009 # B FATHOM DR
71562840,"HUNT,  RICHARD F", ,1009 # B FATHOM DR

и запустив

mlr --csv -N sort -f 4 then step -a counter -f 4 -g 4 then filter '$4_counter==1' then cut -x -f 4_counter input.csv >output.csv

, вы получите

71523180,PRASAD  JAMES ANAND, ,#3 ALEX BOYD LINK HILLSBORO
71508050,"HUNT,  RICHARD F", ,1009 # B FATHOM DR
0 голосов
/ 30 мая 2020

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

Но если вы хотите сохранить все, тогда добавление предложения «или ничего» подойдет Это.

awk -F ',' '!seen[$4]++||$4!=""' 
...