/ Forside / Teknologi / Operativsystemer / Linux / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Linux
#NavnPoint
o.v.n. 11177
peque 7911
dk 4814
e.c 2359
Uranus 1334
emesen 1334
stone47 1307
linuxrules 1214
Octon 1100
10  BjarneD 875
Grep af følgende logfil
Fra : Burns


Dato : 05-05-04 12:34

Vi har en logfil som ligner dette:

Line 1, Me, In
Data 91,1,2,24,7,1,8,27
Line 1, Out
Data 1,2,2,2,7,1,8,72,23
Data 91,1,2,24,7,1,8,27
Data 2,2,232,7,21,438,7,2
Line 211, Me, In
Data 1,2,2,2,7,1,8,72,23
Data 2,2,232,7,21,438,7,2
Line 211, In
Data 2,2,232,7,21,438,7,2

Jeg vil gerne have vist alle felter, hvor "Line" og "Me" indgår på første
linie og så skal den tage alle linier ned til næste "Line". Dvs. output skal
gerne være følgende:

Line 1, Me, In
Data 91,1,2,24,7,1,8,27
Line 211, Me, In
Data 1,2,2,2,7,1,8,72,23
Data 2,2,232,7,21,438,7,2

Jeg kan såmen lige finde ud af den første grep, "cat text.txt | grep Line |
grep Me" men hvordan får man den så til at tage resten med indtil næste
"Line"? Skal man ind på noget awk?



 
 
Erlo Haugen (05-05-2004)
Kommentar
Fra : Erlo Haugen


Dato : 05-05-04 14:22

Burns wrote:

> Vi har en logfil som ligner dette:
>
> Line 1, Me, In
> Data 91,1,2,24,7,1,8,27
> Line 1, Out
> Data 1,2,2,2,7,1,8,72,23
> Data 91,1,2,24,7,1,8,27
> Data 2,2,232,7,21,438,7,2
> Line 211, Me, In
> Data 1,2,2,2,7,1,8,72,23
> Data 2,2,232,7,21,438,7,2
> Line 211, In
> Data 2,2,232,7,21,438,7,2
>
> Jeg vil gerne have vist alle felter, hvor "Line" og "Me" indgår på første
> linie og så skal den tage alle linier ned til næste "Line". Dvs. output skal
> gerne være følgende:
>
> Line 1, Me, In
> Data 91,1,2,24,7,1,8,27
> Line 211, Me, In
> Data 1,2,2,2,7,1,8,72,23
> Data 2,2,232,7,21,438,7,2
>
> Jeg kan såmen lige finde ud af den første grep, "cat text.txt | grep Line |
> grep Me" men hvordan får man den så til at tage resten med indtil næste
> "Line"? Skal man ind på noget awk?
>
>
Jeg vil mene at sed + awk eller perl er gode kandidater til opgaven.

--
Erlo
-----
Remove underscores from mail address.
The statements and opinions are mine and does not
neccesarily reflect those of my employers

Burns (05-05-2004)
Kommentar
Fra : Burns


Dato : 05-05-04 14:33

> Jeg vil mene at sed + awk eller perl er gode kandidater til opgaven.

Jo, jo - men hvordan? Jeg er ikke ligefrem nogen ørn til det, men kender da
lidt til grep.



Peter Jensen (05-05-2004)
Kommentar
Fra : Peter Jensen


Dato : 05-05-04 19:24

Burns wrote:

> Vi har en logfil som ligner dette:
>
> Line 1, Me, In
> Data 91,1,2,24,7,1,8,27
> Line 1, Out
> Data 1,2,2,2,7,1,8,72,23
> Data 91,1,2,24,7,1,8,27
> Data 2,2,232,7,21,438,7,2
> Line 211, Me, In
> Data 1,2,2,2,7,1,8,72,23
> Data 2,2,232,7,21,438,7,2
> Line 211, In
> Data 2,2,232,7,21,438,7,2
>
> Jeg vil gerne have vist alle felter, hvor "Line" og "Me" indgår på
> første linie og så skal den tage alle linier ned til næste "Line".
> Dvs. output skal gerne være følgende:
>
> Line 1, Me, In
> Data 91,1,2,24,7,1,8,27
> Line 211, Me, In
> Data 1,2,2,2,7,1,8,72,23
> Data 2,2,232,7,21,438,7,2

Klart en opgave for 'csplit'. Prøv dette script:

========================================================================
#!/bin/bash

if [ $# != 1 ]
then
echo "Usage: $0 <logfile>"
exit 1
fi

RND=$RANDOM
while [ -e /tmp/logparser.$$.$RND ]
do
RND=$RANDOM
done
mkdir /tmp/logparser.$$.$RND

csplit -q -n 10 -z -f /tmp/logparser.$$.$RND/splitfile. $1 '/Line/' '{*}'
find /tmp/logparser.$$.$RND/ |\
xargs grep '^Line.*Me.*$' -l |\
xargs cat

rm -r /tmp/logparser.$$.$RND
========================================================================

> Jeg kan såmen lige finde ud af den første grep, "cat text.txt | grep
> Line | grep Me"

Useless use of cat. 'grep' tager gerne filnavne som parametre, og de to
'grep' kald viser at du nok burde læse 'man 7 regex' en ekstra gang ...

> men hvordan får man den så til at tage resten med
> indtil næste "Line"? Skal man ind på noget awk?

Hvorfor genopfinde den dybe talerken? 'csplit' har funktionaliteten,
hvilket jeg bare pakkede pænt ind i et lille script.

--
PeKaJe

The brain is a wonderful organ; it starts working the moment you get up
in the morning, and does not stop until you get to work.

Burns (06-05-2004)
Kommentar
Fra : Burns


Dato : 06-05-04 08:33

> Klart en opgave for 'csplit'. Prøv dette script:
> #!/bin/bash
> if [ $# != 1 ]
> then
> echo "Usage: $0 <logfile>"
> exit 1
> fi
> RND=$RANDOM
> while [ -e /tmp/logparser.$$.$RND ]
> do
> RND=$RANDOM
> done
> mkdir /tmp/logparser.$$.$RND
> csplit -q -n 10 -z -f /tmp/logparser.$$.$RND/splitfile. $1 '/Line/' '{*}'
> find /tmp/logparser.$$.$RND/ |\
> xargs grep '^Line.*Me.*$' -l |\
> xargs cat
> rm -r /tmp/logparser.$$.$RND

Når jeg køre filen "./shell.sh data.txt" får jeg følgende output:
csplit: illegal option -- q
usage: csplit [-ks] [-f prefix] [-n number] file args ...

Det er en FreeBSD, og den har ikke mulighed for -q og -z. Jeg prøvede så at
fjerne de to, men så virker det jo måske klart nok stadigt ikke.

> > Jeg kan såmen lige finde ud af den første grep, "cat text.txt | grep
> > Line | grep Me"
>
> Useless use of cat. 'grep' tager gerne filnavne som parametre, og de to
> 'grep' kald viser at du nok burde læse 'man 7 regex' en ekstra gang ...

Fordelen ved grep er, at det er standard på alle unix, den er simpel og at
jeg ikke skal til at kode et script - det kan stå på én linie.

> > men hvordan får man den så til at tage resten med
> > indtil næste "Line"? Skal man ind på noget awk?
>
> Hvorfor genopfinde den dybe talerken? 'csplit' har funktionaliteten,
> hvilket jeg bare pakkede pænt ind i et lille script.

Og jeg siger mange tak Jeg kender ikke csplit, men nu vil jeg lige prøve
at sætte mig ind i hvad den kan.



Peter Jensen (06-05-2004)
Kommentar
Fra : Peter Jensen


Dato : 06-05-04 09:51

Burns wrote:

>> Klart en opgave for 'csplit'. Prøv dette script:
>>
>> #!/bin/bash
>> if [ $# != 1 ]
>> then
>> echo "Usage: $0 <logfile>"
>> exit 1
>> fi
>> RND=$RANDOM
>> while [ -e /tmp/logparser.$$.$RND ]
>> do
>> RND=$RANDOM
>> done
>> mkdir /tmp/logparser.$$.$RND
>> csplit -q -n 10 -z -f /tmp/logparser.$$.$RND/splitfile. $1 '/Line/' '{*}'
>> find /tmp/logparser.$$.$RND/ |\
>> xargs grep '^Line.*Me.*$' -l |\
>> xargs cat
>> rm -r /tmp/logparser.$$.$RND
>
> Når jeg køre filen "./shell.sh data.txt" får jeg følgende output:
> csplit: illegal option -- q
> usage: csplit [-ks] [-f prefix] [-n number] file args ...
>
> Det er en FreeBSD,

Doh! Jeg bruger Linux og GNU's 'coreutils'. Du kunne selvfølgeligt
have nævnt det i din OP, men jeg ville nu alligevel ikke have vidst at
der var forskel på de to implementeringer

> og den har ikke mulighed for -q og -z. Jeg prøvede så at fjerne de to,
> men så virker det jo måske klart nok stadigt ikke.

-z er egentligt ikke nødvendig, men at -q mangler giver mindre problemer
i min implementation. Prøv at erstatte den csplit linie med dette:

csplit -n 10 -f /tmp/logparser.$$.$RND/splitfile. $1 '/Line/' '{*}' >/dev/null

Men hov ... Jeg kigger lige på 'man csplit' igen, og der står -q heller
ikke nævnt! Kun --quiet. Til gengæld står -s nævnt i samme linje.
Måske -q bare skal erstattes med -s? Det virker i hvert fald også her.

>> Useless use of cat. 'grep' tager gerne filnavne som parametre, og de to
>> 'grep' kald viser at du nok burde læse 'man 7 regex' en ekstra gang ...
>
> Fordelen ved grep er, at det er standard på alle unix, den er simpel og at
> jeg ikke skal til at kode et script - det kan stå på én linie.

Ja, men det var heller ikke det jeg brokkede mig over. Jeg mente bare
at du brugte grep på en langt fra optimal måde i det lille eksempel

>> Hvorfor genopfinde den dybe talerken? 'csplit' har funktionaliteten,
>> hvilket jeg bare pakkede pænt ind i et lille script.
>
> Og jeg siger mange tak Jeg kender ikke csplit, men nu vil jeg lige prøve
> at sætte mig ind i hvad den kan.

Ja den kan bruges til mange sjove ting. Den er mest brugbar til at dele
log-filer op, men jeg har også brugt den til at dele DVD-undertekster
op, så jeg kunne systematisere redigeringen af dem.

Enjoy!

--
PeKaJe

When you don't know what to do, walk fast and look worried.

Burns (06-05-2004)
Kommentar
Fra : Burns


Dato : 06-05-04 10:44

> Doh! Jeg bruger Linux og GNU's 'coreutils'. Du kunne selvfølgeligt
> have nævnt det i din OP, men jeg ville nu alligevel ikke have vidst at
> der var forskel på de to implementeringer

Det kunne jeg - beklager. Det er jo sådan noget man/jeg først tænker på
efter man har postet, at det igrunden er en ganske brugbar information

Følgende linier giver følgende fejl:

csplit -n 10 -f /tmp/logparser.$$.$RND/splitfile. $1 '/Line/' '{*}'
>/dev/null
og
csplit -s -n 10 -f /tmp/logparser.$$.$RND/splitfile. $1 '/Line/' '{*}'

su-2.05b# ./shell.sh data.txt
csplit: 10: suffix too long (limit 9)

Hvis jeg sætter "-n 10" til at være "-n 9" kommer denne (måske klart nok?):
csplit: *}: bad repetition count



Peter Jensen (06-05-2004)
Kommentar
Fra : Peter Jensen


Dato : 06-05-04 12:00

Burns wrote:

>> Doh! Jeg bruger Linux og GNU's 'coreutils'. Du kunne selvfølgeligt
>> have nævnt det i din OP, men jeg ville nu alligevel ikke have vidst at
>> der var forskel på de to implementeringer
>
> Det kunne jeg - beklager. Det er jo sådan noget man/jeg først tænker på
> efter man har postet, at det igrunden er en ganske brugbar information

Ja, men det er alligevel først nu at jeg ser hvor *lidt* BSD's 'csplit'
egentligt kan ...

> Følgende linier giver følgende fejl:
>
> csplit -n 10 -f /tmp/logparser.$$.$RND/splitfile. $1 '/Line/' '{*}' >/dev/null
> og
> csplit -s -n 10 -f /tmp/logparser.$$.$RND/splitfile. $1 '/Line/' '{*}'
>
> su-2.05b# ./shell.sh data.txt
> csplit: 10: suffix too long (limit 9)

Underligt valg af grænse. Så længe filsystemet ikke brokker sig skulle
der da ikke være nogle problemer med længere filnavne ...

> Hvis jeg sætter "-n 10" til at være "-n 9" kommer denne (måske klart nok?):
> csplit: *}: bad repetition count

I GNU's implementation betyder {*} "repeat the previous pattern as many
times as possible". Denne findes tilsyneladende ikke i BSD's, så der
skal i stedet stå en integer. Min 'csplit' brokker sig hvis man giver
et for stort tal, så en 'grep -c' kan bruges til at finde den rigtige
værdi. Prøv nu med dette script:

========================================================================
#!/bin/bash

if [ $# != 1 ]
then
echo "Usage: $0 <logfile>"
exit 1
fi

RND=$RANDOM
while [ -e /tmp/logparser.$$.$RND ]
do
RND=$RANDOM
done
mkdir /tmp/logparser.$$.$RND

csplit -s -n 9 -f /tmp/logparser.$$.$RND/splitfile. $1 '/Line/' "{$(( $(grep -c '^Line.*$' $1) - 1 ))}"
find /tmp/logparser.$$.$RND/ |\
xargs grep '^Line.*Me.*$' -l |\
sort |\
xargs cat

rm -r /tmp/logparser.$$.$RND
========================================================================

Jeg skød også lige en 'sort' ind, da det ellers ikke er garanteret at
output kommer i samme rækkefølge som input. Og ja, det er grimt, men
det virker på min maskine og det skulle være BSD-safe.

--
PeKaJe

Exhilaration is that feeling you get just after a great idea hits you,
and just before you realize what is wrong with it.

Burns (10-05-2004)
Kommentar
Fra : Burns


Dato : 10-05-04 09:09

> Jeg skød også lige en 'sort' ind, da det ellers ikke er garanteret at
> output kommer i samme rækkefølge som input. Og ja, det er grimt, men
> det virker på min maskine og det skulle være BSD-safe.

Hmm.. jeg tror ikke, at jeg får samme output som du gør?

su-2.05b# ./shell.sh data.txt
csplit: Line: no match

su-2.05b# more shell.sh
#!/usr/local/bin/bash
RND=$RANDOM
while [ -e /tmp/logparser.$$.$RND ]
do
RND=$RANDOM
done
mkdir /tmp/logparser.$$.$RND
csplit -s -n 9 -f /tmp/logparser.$$.$RND/splitfile. $1 '/Line/' "{$((
$(grep -c '^Line.*$' $1) - 1 ))}"
find /tmp/logparser.$$.$RND/ |\
xargs grep '^Line.*Me.*$' -l |\
sort |\
xargs cat
rm -r /tmp/logparser.$$.$RND

su-2.05b# more data.txt
Line 1, Me, In
Data 91,1,2,24,7,1,8,27
Line 1, Out
Data 1,2,2,2,7,1,8,72,23
Data 91,1,2,24,7,1,8,27
Data 2,2,232,7,21,438,7,2
Line 211, Me, In
Data 1,2,2,2,7,1,8,72,23
Data 2,2,232,7,21,438,7,2
Line 211, In
Data 2,2,232,7,21,438,7,2



Søg
Reklame
Statistik
Spørgsmål : 177551
Tips : 31968
Nyheder : 719565
Indlæg : 6408834
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste