Mam plik zawierający linie jako
proto=tcp/http sent=144 rcvd=52 spkt=3
proto=tcp/https sent=145 rcvd=52 spkt=3
proto=udp/dns sent=144 rcvd=52 spkt=3
I trzeba wyodrębnić wartość proto który jest tcp/http
, tcp/https
, udp/dns
.
Do tej pory próbowałem tego, grep -o 'proto=[^/]*/'
ale tylko w stanie wyodrębnić wartość jako proto=tcp/
.
sed
,awk
lubperl
niegrep
.Odpowiedzi:
Zakładając, że jest to związane z twoim poprzednim pytaniem , idziesz niewłaściwą ścieżką. Zamiast próbować poskładać fragmenty skryptów, które w pewien sposób będą robić to, co chcesz przez większość czasu i musisz uzyskać zupełnie inny skrypt za każdym razem, gdy będziesz musiał zrobić coś choć trochę innego, po prostu stwórz 1 skrypt, który może przeanalizować twój plik wejściowy do tablicy (
f[]
poniżej), która odwzorowuje nazwy pól (tagi) na ich wartości, a następnie możesz zrobić, co chcesz z wynikiem, np. biorąc pod uwagę ten plik wejściowy z poprzedniego pytania:możemy napisać skrypt awk, który tworzy tablicę wartości indeksowanych według ich nazw / znaczników:
i biorąc pod uwagę, że możesz robić, co chcesz z danymi, po prostu odwołuj się do nich za pomocą nazw pól, np. używając GNU awk
-e
dla ułatwienia mieszania skryptu w pliku ze skryptem wiersza poleceń:źródło
perl
może być łatwiejszy w użyciu.awk
ised
skrypty są zwykle prostsze,perl
ponieważ jest to w zasadzie ich nadzbiór, z dodatkowymi funkcjami do typowych zadań.s/old/new/g
a sed nie jest awk, więc odłóżmy to na bok. Całkowicie się nie zgadzam, że skomplikowane skrypty awk są prostsze w perlu. Oczywiście mogą być krótsze, ale zwięzłość nie jest pożądanym atrybutem oprogramowania, jest to zwięzłe i niezwykle rzadko mają one jakąkolwiek rzeczywistą korzyść, a ponadto są znacznie trudniejsze do odczytania, dlatego ludzie publikują takie rzeczy jak zoitz.com / archives / 13 o perlu i nazywają go językiem tylko do zapisu, w przeciwieństwie do awk. Nadal chciałbym zobaczyć perla równoważnego temuZa pomocą
grep -o
musisz dopasować dokładnie to, co chcesz wyodrębnić. Ponieważ nie chcesz wyodrębniaćproto=
ciągu, nie powinieneś go dopasowywać.Rozszerzone wyrażenie regularne, które pasowałoby do jednego
tcp
lubudp
po którym następuje ukośnik i niepusty ciąg alfanumeryczny toZastosowanie tego do danych:
Aby upewnić się, że robimy to tylko w wierszach rozpoczynających się od ciągu
proto=
:Z
sed
, usuwając wszystko przed pierwszym=
i po pierwszym pustym znaku:Aby mieć pewność, że robimy to tylko w wierszach rozpoczynających się od łańcucha
proto=
, możesz wstawić ten sam krok wstępnego przetwarzaniagrep
jak powyżej lub możesz użyćTutaj pomijamy domyślne wyjście z
-n
opcją, a następnie uruchamiamy podstawienia i wyraźny wydruk linii tylko wtedy, gdy linia pasuje^proto=
.Za
awk
pomocą domyślnego separatora pól, a następnie podzielenie pierwszego pola=
i wydrukowanie jego drugiego bitu:Aby mieć pewność, że robimy to tylko w wierszach rozpoczynających się od łańcucha
proto=
, możesz wstawić ten sam krok wstępnego przetwarzaniagrep
jak powyżej lub możesz użyćźródło
Jeśli korzystasz z GNU grep (dla
-P
opcji), możesz użyć:Tutaj dopasowujemy
proto=
ciąg, aby upewnić się, że wyodrębniamy poprawną kolumnę, ale następnie odrzucamy ją z wyniku za pomocą\K
flagi.Powyższe zakłada, że kolumny są rozdzielone spacjami. Jeśli tabulatory są również prawidłowym separatorem, użyłbyś
\S
do dopasowania znaków spacji, więc komenda wyglądałaby następująco:Jeśli chcesz również chronić przed polami dopasowania, w których
proto=
znajduje się podłańcuch, taki jak athisisnotaproto=tcp/https
, możesz dodać granicę słów za pomocą\b
:źródło
grep -oP 'proto=\K\S+'
. Poproto=tcp/http
spacji może występować tabulator zamiast spacji, w\S
przeciwieństwie do[^ ]
pasujących do znaków spacji.-o
jest to również GNUism.-P
jest obsługiwany tylko przez GNU,grep
jeśli jest zbudowany z obsługą PCRE (opcjonalnie w czasie kompilacji).Używanie
awk
:$1 ~ "proto"
upewnimy się, że podejmujemy działania tylko na wierszach zproto
pierwszej kolumnysub(/proto=/, "")
usunieproto=
z wejściaprint $1
wypisuje pozostałą kolumnęźródło
Kodowanie golfa w
grep
rozwiązaniachlub nawet
źródło
Za pomocą
cut
polecenia:źródło
http
idns
.Po prostu inne
grep
rozwiązanie:I podobny z
sed
drukowaniem tylko dopasowanej przechwyconej grupy:źródło
Inne
awk
podejście:Spowoduje to ustawienie separatora pól awk na jeden
=
lub spację. Następnie, jeśli linia pasuje do a=
, następnie alboud
albotc
po nimp
, wydrukuj drugie pole.Innym
sed
podejściem (nie przenośny do wszystkich wersjised
, ale współpracuje z GNUsed
):Te
-n
środki „nie drukować” i-E
umożliwia rozszerzonych wyrażeń regularnych, które dają nam\S
do „nie-białych znaków”+
na „jeden lub więcej” i nawiasów do przechwytywania. Wreszcie,/p
na końcu sprawi, że sed wydrukuje linię tylko wtedy, gdy operacja zakończyła się powodzeniem, więc jeśli wystąpiło dopasowanie dla operatora podstawienia.I perlowy:
Te
-n
środki „czytać wiersz po wierszu pliku wejściowego i zastosować skrypt podany przez-e
każdej linii”.-l
Dodaje się do każdej nowej liniiprint
połączenia (i usuwa nowe linie wychodzące z wejścia). Sam skrypt wypisze najdłuższy ciąg znaków niebiałych spacji znalezionych poproto=
.źródło
-E
staje się coraz bardziej przenośny, ale\S
nie jest.[^[:space:]]
jest bardziej przenośnym odpowiednikiem.Oto inne rozwiązanie dość proste:
źródło
grep
nic nie pasuje.[tc,ud]\*\\/.*
szuka jednego wystąpieniat
, lubc
, lub,
lubu
lubd
, po którym następuje dosłowny*
znak, a następnie ap
i odwrotny ukośnik. Prawdopodobnie miałeś na myśligrep -Eo '(tc|ud)p/.* ' file | awk '{print $1}'
. Ale wtedy, jeśli używasz awk, można również zrobić całość w awk:awk -F'[= ]' '/(tc|ud)p/{print $2}' file
.[tc,ud]p
oznacza „jedent
,c
,,
,u
lubd
po przezp
. Więc pasuje tu tylko dlatego, żetcp
macp
iudp
madp
. Ale to też pasuje,p
lubtp
itd. Również teraz, że masz*
, to pasujeppp
jak dobrze (the*
. oznacza „0 lub więcej”, więc będzie on pasował nawet gdy nie pasuje) nie chcesz klasę postaci ([ ]
), co chcesz to grupa:(tc|ud)
(korzystanie z-E
flagągrep
). Ponadto,.*
czyni go dopasuj całą linię\*
aby pierwszy*
w swoim poleceniu pojawił się jako *, a nie kursywą. Po umieszczeniu polecenia w formacie kodu spowodowałeś\
pojawienie się przed nim*
(co spowodowało niepowodzenie polecenia). Gdy edytujesz posty innych osób, uważaj na zmianę wyglądu posta w ten sposób.ppp
. Oczywiście masz rację, że będzie on pasował,p
albotp
- albouucp
,ttp
,cutp
,ductp
lubd,up
.źródło
opcje cięcia:
-f
- pole-d
- delimetrźródło