2012-11-03 14 views
6

Próbuję zwrócić pierwsze wystąpienie wielu ciągów, tzn. Chcę wybrać wiersze z poniższego tekstu, w którym występuje pierwsze wystąpienie 1259, 3009 i 1589.Konieczne grep dla pierwszych wystąpień wielu ciągów znaków

ADWN 1259 11:00 B23 

ADWN 3009 12:00 B19 

DDWN  723 11:30 B04 

ADWN 1589 14:20 B12 

ADWN 1259 11:10 B23 

DDWN 2534 13:00 B16 

ADWN 3009 11:50 B14 

To daje mi wszystkie mecze:

grep '1259\|3009\|1589' somelog.log 

i to daje mi tylko pierwszy mecz

grep -m 1 '1259\|3009\|1589' somelog.log 

chcę wrócić następujące:

ADWN 1259 11:00 B23 

ADWN 3009 12:00 B19 

ADWN 1589 14:20 B12 

I myślę, że tworzenie pliku z wymaganiem uired wartości, a następnie zapętlenie pliku, przekazanie każdego numeru osobno do polecenia grep da mi to, czego szukam, ale nie znalazłem tego przykładu. Czy istnieje proste rozwiązanie tego problemu, czy pętla jest najlepszym sposobem na poradzenie sobie z tym problemem, czy ten przykład został już odebrany w innym miejscu?

Dzięki z góry za swoje pomysły i suggestions--

Clyde

Odpowiedz

4

Jednym ze sposobów, używając awk:

awk '!array[$2]++ && $2 ~ /^1259$|^3009$|^1589$/' file.txt 

Wyniki:

ADWN 1259 11:00 B23 
ADWN 3009 12:00 B19 
ADWN 1589 14:20 B12 

edit:

Naprawdę powinienem wejść w nawyk czytania pierwszego pytania. Widzę, że myślisz o utworzeniu pliku z wartościami, które chcesz znaleźć w pierwszym wystąpieniu. Umieść je w pliku o nazwie values.txt z jedną wartością na linię. Na przykład; oto treść values.txt:

1259 
3009 
1589 

Następnie uruchom to:

awk 'FNR==NR { array[$0]++; next } $2 in array { print; delete array[$2] }' values.txt file.txt 

Wyniki:

ADWN 1259 11:00 B23 
ADWN 3009 12:00 B19 
ADWN 1589 14:20 B12 

1-ty wyjaśnienie polecenie:

Jeśli drugą kolumnę ($2) jest równa jednej z wymienionych wartości, dodaj ją do tablicy, jeśli jeszcze jej tam nie ma. awk domyślnie drukuje całą linię.

2-ta wyjaśnienie polecenie:

FNR jest liczba rekordów w stosunku do bieżącego pliku wejściowego.
NR to całkowita liczba rekordów.

Konstrukcja FNR==NR { ... } jest prawdziwa tylko dla pierwszego pliku wejściowego.Tak więc dla każdej linii w values.txt dodajemy całą linię ($0) do tablicy (nazwałem ją tablicą, ale można nadać jej inną nazwę). next Wymusza odczytanie następnej linii w awk (i pominięcie przetwarzania pozostałej części polecenia). Kiedy FNR==NR przestaje być prawdziwy, czytany jest drugi plik z listy argumentów. Następnie sprawdzamy drugą kolumnę ($2) w tablicy, jeśli jest tam, wydrukuj ją i usuń z tablicy. Używając delete, ustawiamy maksymalną liczbę jeden.

+0

Steve - dzięki, że robi to, o co prosiłem, zwraca pierwsze wystąpienie każdej wartości. Mam kilka do zrobienia w awk, i rozumiem dokładnie, co robi kod –

+1

Mogę dodać szybkie wyjaśnienie, jeśli chcesz. Trzymaj się ... – Steve

+0

Miło, doceniam wyjaśnienie - niektóre z tych rzeczy mogą być dość nieprzejrzyste! Z pewnością będę w stanie to wykorzystać, dzięki jeszcze raz! –

-1

Spróbuj tego. To może nie działać w zależności od wersji grep:

grep -m 1 -e pattern1 -e pattern2 
+0

Niestety, dzięki temu fragmentowi zwróciłem tylko pierwszy wzór, dziękuję. –

0

ten będzie też działa.

for i in $(cut -d " " -f1 somelog.log | sort -u); do LC_ALL=C fgrep -m1 "$i" somelog.log; done 
Powiązane problemy