У меня есть .csv файл как это:
stack2@example.com,2009-11-27 01:05:47.893000000,example.net,127.0.0.1
overflow@example.com,2009-11-27 00:58:29.793000000,example.net,255.255.255.0
overflow@example.com,2009-11-27 00:58:29.646465785,example.net,256.255.255.0
...
Я должен удалить дублирующиеся электронные письма (вся строка) из файла (т.е. одна из строк, содержащих overflow@example.com
в вышеупомянутом примере). Как я использую uniq
только на поле 1 (разделенный запятыми)? Согласно man
, uniq
не имеет опций для столбцов.
Я попробовал что-то sort | uniq
но это не работает.
sort -u -t, -k1,1 file
-u
для уникального -t,
, поэтому запятая является разделителем -k1,1
для ключевого поля 1 Результат теста:
overflow@domain2.com,2009-11-27 00:58:29.793000000,xx3.net,255.255.255.0
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
awk -F"," '!_[$1]++' file
-F
устанавливает разделитель полей. $ 1
- это первое поле. _ [val]
ищет val
в хэше _
(обычная переменная). ++
приращение и возвращает старое значение. !
возвращает логическое «нет». или если вы хотите использовать uniq:
дает:
1 01:05:47.893000000 2009-11-27 tack2@domain.com
2 00:58:29.793000000 2009-11-27 overflow@domain2.com
1
ну, проще, чем изолировать папку столбец с awk, если вам нужно удалить все с определенным значением для данного файла, почему бы просто не выполнить grep -v:
например, чтобы удалить все со значением "col2" во втором месте строка: col1, col2, col3, col4
grep -v ',col2,' file > file_minus_offending_lines
Если этого недостаточно, потому что некоторые строки могут быть неправильно разделены из-за того, что соответствующее значение может отображаться в другом столбце, вы можете сделать что-то вроде этого:
awk, чтобы изолировать проблемный столбец: например
awk -F, '{print $2 "|" $line}'
-F устанавливает поле, разделенное на ",", $ 2 означает столбец 2, за которым следует некоторый настраиваемый разделитель, а затем вся строка. Затем вы можете отфильтровать, удалив строки, которые начинаются с оскорбительного значения:
awk -F, '{print $2 "|" $line}' | grep -v ^BAD_VALUE
, а затем удалите материал перед разделителем:
awk -F, '{print $2 "|" $line}' | grep -v ^BAD_VALUE | sed 's/.*|//g'
(обратите внимание: команда sed небрежна, потому что она не включает экранирование значений.Также шаблон sed действительно должен быть чем-то вроде "[^ |] +" (то есть чем угодно, кроме разделителя). Но, надеюсь, это достаточно ясно.
Сначала отсортировав файл с помощью sort
, вы можете применить uniq
.
Похоже, файл сортируется отлично:
$ cat test.csv
overflow@domain2.com,2009-11-27 00:58:29.793000000,xx3.net,255.255.255.0
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
overflow@domain2.com,2009-11-27 00:58:29.646465785,2x3.net,256.255.255.0
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack3@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack4@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
$ sort test.csv
overflow@domain2.com,2009-11-27 00:58:29.646465785,2x3.net,256.255.255.0
overflow@domain2.com,2009-11-27 00:58:29.793000000,xx3.net,255.255.255.0
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack3@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack4@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
$ sort test.csv | uniq
overflow@domain2.com,2009-11-27 00:58:29.646465785,2x3.net,256.255.255.0
overflow@domain2.com,2009-11-27 00:58:29.793000000,xx3.net,255.255.255.0
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack3@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack4@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
] Вы также можете использовать магию AWK:
$ awk -F, '{ lines[$1] = $0 } END { for (l in lines) print lines[l] }' test.csv
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack4@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
stack3@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
overflow@domain2.com,2009-11-27 00:58:29.646465785,2x3.net,256.255.255.0