Mam plik .csv taki jak ten:
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
...
Muszę usunąć zduplikowane wiadomości e-mail (całą linię) z pliku (tj. Jedną z linii zawartych [email protected]
w powyższym przykładzie). Jak używać uniq
tylko na polu 1 (oddzielone przecinkami)? Według man
, uniq
nie ma opcji dla kolumn.
Próbowałem czegoś, sort | uniq
ale to nie działa.
man sort
). Oznacza pozycję początkową i końcową.sort
mówi „s podręcznika:« ze należy sprawdzić, a bez ścisłej kolejności , wyjście tylko pierwszy z taką samą metę .» Jest to zatem „pierwsze wystąpienie duplikatu przed sortowaniem”.-u
--unique
-c
-c
-F
ustawia separator pól.$1
jest pierwszym polem._[val]
wyszukujeval
skrót_
(zmienna regularna).++
zwiększ i zwróć starą wartość.!
zwraca logiczne nie.źródło
awk -F',' '{ x[$1]=$0 } END { for (i in x) print x[i] }' file
!_[$1][$2]++
można użyć do sortowania według pierwszych dwóch pól. Mójawk
-fu nie jest jednak wystarczająco silny, aby móc wyróżniać się na wielu polach. :(Aby rozważyć wiele kolumn.
Sortuj i podaj unikalną listę na podstawie kolumny 1 i kolumny 3:
-t :
dwukropek jest separatorem-k 1,1 -k 3,3
na podstawie kolumny 1 i kolumny 3źródło
lub jeśli chcesz użyć uniq:
<mycvs.cvs tr -s ',' ' ' | awk '{print $3" "$2" "$1}' | uniq -c -f2
daje:
źródło
cat
! Zamiast pipować do tr, po prostu pozwól tr odczytać plik za pomocą<
. Rurociągicat
to powszechna niepotrzebna komplikacja stosowana przez nowicjuszy. W przypadku dużych ilości danych można uzyskać efekt wydajności.rev
.Jeśli chcesz zachować ostatni z duplikatów, którego możesz użyć
To było moje wymaganie
tutaj
tac
odwróci plik linia po liniiźródło
Oto bardzo fajny sposób.
Najpierw sformatuj zawartość, tak aby kolumna, którą chcesz porównać pod kątem niepowtarzalności, ma stałą szerokość. Jednym ze sposobów jest użycie awk printf ze specyfikatorem szerokości pola / kolumny („% 15s”).
Teraz można użyć opcji -f i -w uniq, aby pominąć poprzednie pola / kolumny i określić szerokość porównania (szerokość kolumny).
Oto trzy przykłady.
W pierwszym przykładzie ...
1) Tymczasowo ustaw kolumnę będącą przedmiotem zainteresowania na większą lub równą maksymalnej szerokości pola.
2) Użyj opcji -f uniq, aby pominąć poprzednie kolumny, i użyj opcji -w uniq, aby ograniczyć szerokość do tmp_fixed_width.
3) Usuń końcowe spacje z kolumny, aby „przywrócić” jej szerokość (zakładając, że wcześniej nie było końcowych spacji).
W drugim przykładzie ...
Utwórz nową kolumnę uniq 1. Następnie usuń ją po zastosowaniu filtra uniq.
Trzeci przykład jest taki sam jak drugi, ale dla wielu kolumn.
źródło
cóż, prostsze niż izolowanie kolumny za pomocą awk, jeśli chcesz usunąć wszystko o określonej wartości dla danego pliku, dlaczego po prostu nie zrobić grep -v:
np. aby usunąć wszystko o wartości „col2” w wierszu drugiego miejsca: col1, col2, col3, col4
Jeśli nie jest to wystarczająco dobre, ponieważ niektóre wiersze mogą zostać nieprawidłowo usunięte, prawdopodobnie wyświetlając pasującą wartość w innej kolumnie, możesz zrobić coś takiego:
awk, aby wyizolować naruszającą kolumnę: np
-F ustawia pole rozdzielane na „,”, 2 $ oznacza kolumnę 2, a następnie niestandardowy separator, a następnie całą linię. Następnie możesz filtrować, usuwając linie zaczynające się od wartości obrażającej:
a następnie usuń elementy przed separatorem:
(uwaga - polecenie sed jest niedbałe, ponieważ nie zawiera wartości zmiany znaczenia. Wzorzec sed powinien być tak naprawdę taki jak „[^ |] +” (tzn. cokolwiek, co nie jest ogranicznikiem). Ale mam nadzieję, że jest to wystarczająco jasne.
źródło
Sortując
sort
najpierw plik , możesz następnie zastosowaćuniq
.Wygląda na to, że plik jest w porządku:
Możesz także wykonać magię AWK:
źródło
sort
touniq
,sort
należy to zrobić przed zrobieniem,uniq
inaczej nie zadziała (ale możesz pominąć drugie polecenie i po prostu użyćsort -u
). Fromuniq(1)
: „Filtruj sąsiadujące pasujące linie z INPUT (lub standardowego wejścia), pisząc do OUTPUT (lub standardowego wyjścia).”