|
| 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
| |
|
|