2009-09-24 12 views
10

Mam ogromny plik na serwerze UNIX, z której trzeba wyodrębnić pewne częścidostać część linii po grep

Format linii jest

aNumber timestamp commandInformation 

używam komendy

grep LATENCY file.log | grep CMDTYPE=NEW 

do odfiltrowania niektórych linii, które chcę. Chcę tylko, aby znacznik czasu części i 9 ostatnich znaków z linii został zwrócony, a nie cała linia. Jak mogę to zrobić?

Odpowiedz

10

Zastosowanie awk(1):

awk ' { print $2" "substr($0,length($0)-8) }' 
+1

+1 za to szybciej niż ja :) –

1

Można użyć awk następująco:

grep LATENCY file.log | grep CMDTYPE=NEW | awk '{print $2,substr($0,length($0)-9,9)}' 
+0

Czy nie za pomocą $ 0 zapewnić wyświetlanie końca linii zamiast tylko końca trzeciego słowa? –

+0

@Yannick: tak, założyłem bez powodu, że "commandInformation" będzie tylko jednym słowem. Naprawiono post z twoją sugestią, dzięki! –

0

Nie ma potrzeby korzystania grep, awk można zrobić również:

awk '/LATENCY/ && /CMDTYPE=NEW/ {print $2 " " substr($0, length($0)-8)}' file 
2

I Zamierzam argumentować perl jest lepszym wyborem niż awk tutaj:

perl -ne 'next if ! (/LATENCY|CMDTYPE=NEW/ && /^\d+.*\s+(.*)\s+.*(.{9})$/); print "$2 $3\n";' 

Wybiór jest bardziej wytrzymały, co pozwala pominąć linie, które nie pasują do bardziej rygorystycznego wzoru. Powyższe skrypty awk zobaczą przepełnienia w wywołaniu substr (szczerze mówiąc, nie wiem, co ujemne indeksy robią w awk), jeśli karmisz je uszkodzonymi danymi wejściowymi, takimi jak częściowe linie od końca dziennika.

0

Możesz zrobić wszystko sam z sed:

 
$ echo "234432 12:44:22.432095 LATENCY blah CMDTYPE=NEW foo bar 123456789" | \ 
sed -n '/LATENCY/!b;/CMDTYPE=NEW/!b;s/^.\+\s\+\([0-9:.]\+\)\s.\+\(.........\)$/\1 \2/; p' 
12:44:22.432095 123456789 
9

cut musi wykonać zadanie

grep something somewhere | grep againsomething | cut -f2 -d' ' 
Powiązane problemy