Mam następujący plik:
AA,true
AA,false
BB,false
CC,false
BB,true
DD,true
Próbuję poszukać duplikatów i usunąć wiersz o wartości kolumny równej true
.
jako wynik powinien być:
AA,false
BB,false
CC,false
DD,true
text-processing
awk
sed
Hani Gotc
źródło
źródło
true
jeśli jest to pierwsza instancja pierwszej kolumny?AA,true AA,false AA,false AA,false
Jaka powinna być wydajność w tym przypadku? Rozumiem, że ten wiersz powinien zostać usunięty tylko wtedy, gdy jest zduplikowany i zawieratrue
jednocześnie. Wfalse
każdym razie wszystkie wiersze powinny pozostać nietknięte. Oznacza to, że w tym przypadku tylkoAA, true
zostaną usunięte. Ale wszystkie odpowiedzi pozostawiają tylko jedną linię -AA,false
. Po prostu ciekawe :)Odpowiedzi:
Aby rozwinąć skrypt pionowo w celu wyjaśnienia:
źródło
Prosta wersja:
„fałsz” sortuje alfabetycznie przed „prawda”, a tutaj polecenie Awk zachowuje pierwszy wiersz tylko dla każdej odrębnej pierwszej wartości pola.
Jeśli chcesz zachować wartość „prawda” zamiast „fałsz”, posortuj ją odwrotnie, przekaż to samo polecenie Awk, a następnie posortuj ponownie w odwrotnej kolejności.
źródło
-u
opcja jest dostępna,sort input.txt | sort -t, -u -k1,1
sort
połączeń? Dlaczego nie tylkosort -ut, -k1,1 input.txt
?-u
zachowa pierwszą znalezioną linię z pliku wejściowego wśród duplikatów ... w danym przypadku dane wejściowe muszą zostać posortowane, zanim-u
będzie można je zastosować ... na przykład:AA,true
zostanie wydrukowane zamiast,AA,false
ponieważ pojawia się jako pierwsze w danej próbce. z tego samego powodu, dla któregoawk -F, '!a[$1]++'
sam nie rozwiąże tego problemuStruktury danych:
%h
którego klucze są pierwszymi polami (AAA, BBB, CCC itp.), A odpowiadającymi im wartościami są liczby określające kolejność napotkania kluczy. Zatem np. Klucz AAA => 0, klucz BBB => 1, klucz CCC => 2.@h
której elementami są linie zawarte w kolejności drukowania. Więc jeśli zarówno prawda, jak i fałsz zostaną znalezione w danych, wówczas wartość fałszu przejdzie do tablicy. OTW, jeśli istnieje jeden typ danych, to byłby obecny.Innym sposobem jest użycie GNU sed:
FWIW, kod równoważny POSIX dla powyższego kodu GNU-sed jest wymieniony poniżej:
Wyjaśnienie
Wyniki
źródło
Dla każdego wiersza wejściowego przechowuj wartość drugiego pola w tablicy asocjacyjnej
a
(używając pierwszego pola jako klucza tablicy) TYLKO, jeśli nie zapisaliśmy jeszcze wartościfalse
tego klucza. Użyj,
dla separatora pola wejściowego i wyjściowego. Wydrukuj tablicę po przeczytaniu wszystkich linii wejściowych.Istotna różnica między tą wersją a wersją DopeGhoti polega na tym, że ta wersja w ogóle nie dba o wartość
$2
, tylko dba o wartość, jeśli w ogólea[$1]
.źródło
sort
Rozwiązanie dwuprzebiegowePrzekazywanie w pierwszej
sort
kolejności klastrów według pola1
zfalse
rekordami poprzedzającymitrue
dla każdego bloku rekordów o wspólnej1
wartości pola . Drugiesort
przejście jest ustawione tak, aby uzyskać jeden rekord dla każdej odrębnej wartości w ramach1
uprzejmości terenowej-u
. Ponieważ-u
implikuje to sortowanie stabilne, uzyskany w ten sposób jeden rekord jest pierwszym napotkanym rekordem dla każdej odrębnej wartości w polu1
- który jest rekordemfalse
w drugim polu ze względu na pracę wykonaną przy pierwszymsort
przejściuźródło