Есть ли способ "uniq" по столбцу?



у меня есть .csv файл, как это:



[email protected],2009-11-27 01:05:47.893000000,example.net,127.0.0.1
[email protected],2009-11-27 00:58:29.793000000,example.net,255.255.255.0
[email protected],2009-11-27 00:58:29.646465785,example.net,256.255.255.0
...


Я должен удалить дубликаты электронной почты (всю строку) из файла (т. е. одну из строк, содержащих [email protected] в приведенном выше примере). Как я могу использовать uniq только на поле 1 (через запятую)? Согласно man,uniq не имеет параметров для столбцов.



Я пробовал что-то с sort | uniq но это не работает.

578   8  

8 ответов:

sort -u -t, -k1,1 file
  • -u уникальный
  • -t, так запятая является разделителем
  • -k1,1 для ключевого поля 1

результат теста:

[email protected],2009-11-27 00:58:29.793000000,xx3.net,255.255.255.0 
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1 
awk -F"," '!_[]++' file
  • -F задает разделитель полей.
  • это первое поле.
  • _[val] ищет val в хэш -_(регулярная переменная).
  • ++ увеличить и вернуть старое значение.
  • ! возвращает логическое не.
  • в конце есть неявная печать.

рассмотреть несколько столбцов.

сортировать и давать уникальный список на основе столбца 1 и столбца 3:

sort -u -t : -k 1,1 -k 3,3 test.txt
  • -t : двоеточие-это разделитель
  • -k 1,1 -k 3,3 на основе столбца 1 и столбца 3

или если вы хотите использовать uniq:

<mycvs.cvs tr -s ',' ' ' | awk '{print " "" "}' | uniq -c -f2

выдает:

1 01:05:47.893000000 2009-11-27 [email protected]
2 00:58:29.793000000 2009-11-27 [email protected]
1

Если вы хотите сохранить последний из дубликатов вы можете использовать

 tac a.csv | sort -u -t, -r -k1,1 |tac

что было моим требованием

здесь

tac перевернет файл строка за строкой

вот очень интересный способ.

сначала отформатируйте содержимое таким образом, чтобы столбец, который будет сравниваться для уникальности, имел фиксированную ширину. Один из способов сделать это-использовать awk printf со спецификатором ширины поля/столбца ("%15s").

Теперь параметры-f и-w uniq можно использовать для пропуска предыдущих полей / столбцов и указания ширины сравнения (ширины столбцов).

вот три примера.

В первом примере...

1) Временно сделайте столбец интереса фиксированной шириной, большей или равной максимальной ширине поля.

2) используйте опцию-F uniq, чтобы пропустить предыдущие столбцы, и используйте опцию-w uniq, чтобы ограничить ширину tmp_fixed_width.

3) Удалите конечные пробелы из столбца ,чтобы" восстановить " его ширину (предполагая, что ранее не было конечных пробелов).

printf "%s" "$str" \
| awk '{ tmp_fixed_width=15; uniq_col=8; w=tmp_fixed_width-length($uniq_col); for (i=0;i<w;i++) { $uniq_col=$uniq_col" "}; printf "%s\n",  }' \
| uniq -f 7 -w 15 \
| awk '{ uniq_col=8; gsub(/ */, "", $uniq_col); printf "%s\n",  }'

во втором примере...

создать новый столбец uniq 1. Затем удалите его после фильтр уник был применен.

printf "%s" "$str" \
| awk '{ uniq_col_1=4; printf "%15s %s\n", uniq_col_1,  }' \
| uniq -f 0 -w 15 \
| awk '{ =""; gsub(/^ */, "", ); printf "%s\n",  }'

третий пример такой же, как и второй, но для нескольких столбцов.

printf "%s" "$str" \
| awk '{ uniq_col_1=4; uniq_col_2=8; printf "%5s %15s %s\n", uniq_col_1, uniq_col_2,  }' \
| uniq -f 0 -w 5 \
| uniq -f 1 -w 15 \
| awk '{ ==""; gsub(/^ */, "", ); printf "%s\n",  }'

ну, проще, чем изолировать столбец с awk, если вам нужно удалить все с определенным значением для данного файла, почему бы просто не сделать grep-v:

например, чтобы удалить все со значением "col2" во втором месте линия: col1, col2, col3, col4

grep -v ',col2,' file > file_minus_offending_lines

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

awk to выделить столбец обидеть : например,

awk -F, '{print  "|" $line}'

- F устанавливает поле, разделенное на",", $2 означает столбец 2, за которым следует некоторый пользовательский разделитель, а затем вся строка. Затем вы можете фильтровать, удаляя строки, которые начать С оскорбительным значением:

 awk -F, '{print  "|" $line}' | grep -v ^BAD_VALUE

а затем раздеть вещи перед разделителем:

awk -F, '{print  "|" $line}' | grep -v ^BAD_VALUE | sed 's/.*|//g'

(Примечание-команда sed небрежна, потому что она не включает экранирование значений. Также шаблон sed действительно должен быть что-то вроде "[^|]+" (т. е. ничего не разделитель). Но, надеюсь, это достаточно ясно.

путем сортировки файла с sort во-первых, вы можете подать заявку uniq.

кажется, чтобы отсортировать файл в порядке:

$ cat test.csv
[email protected],2009-11-27 00:58:29.793000000,xx3.net,255.255.255.0
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
[email protected],2009-11-27 00:58:29.646465785,2x3.net,256.255.255.0 
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1

$ sort test.csv
[email protected],2009-11-27 00:58:29.646465785,2x3.net,256.255.255.0 
[email protected],2009-11-27 00:58:29.793000000,xx3.net,255.255.255.0
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1

$ sort test.csv | uniq
[email protected],2009-11-27 00:58:29.646465785,2x3.net,256.255.255.0 
[email protected],2009-11-27 00:58:29.793000000,xx3.net,255.255.255.0
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1

вы также можете сделать некоторые AWK магии:

$ awk -F, '{ lines[] =  } END { for (l in lines) print lines[l] }' test.csv
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
[email protected],2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
[email protected],2009-11-27 00:58:29.646465785,2x3.net,256.255.255.0 

Comments

    Ничего не найдено.