"Ed Morton" <morton@[EMAIL PROTECTED]
> wrote in message
news:47C25043.1000302@[EMAIL PROTECTED]
>
>
> On 2/24/2008 5:34 PM, DanielC wrote:
>
> [ for the second time - please don't top-post, fixed below]
>
What does this mean?
>
>> "Ed Morton" <morton@[EMAIL PROTECTED]
> wrote in message
>> news:47C1F7E5.9000108@[EMAIL PROTECTED]
>>
>>>
>>>On 2/24/2008 4:36 PM, DanielC wrote:
>>>
>>>>>>$ echo "[2008-02-24 21:07:08.149124] 6451642 196612 547 0 6839170" |
>>>>>>awk
>>>>>>'{print gensub(/\[(....)-(..)-(..) (..):(..):(..).*/,"\\1 \\2 \\3
\\4
>>>>>>\\5
>>>>>>\\6","")}'
>>>>>>2008 02 24 21 07 08
>>>>>
>>>>This is great! I don't know gensub() can do that.
>>>>
>>>>
>>>>
>>>>>>However, # awk -F "[].[]+" 'system("date +%s -d " $2)' /tmp/logfile
>>>>>>doesn't.
>>>>>>
>>>>>
>>>>>Doesn't what? What do you want the output to be?
>>>>
>>>>
>>>>I want # awk -F "[].[]+" 'system("date +%s -d " $2)' /tmp/logfile
>>>>output
>>>>the timestamp like $ awk 'BEGIN {system("date +%s -d " "\"2008-02-24
>>>>09:14:03\"")}' does. However it doesn't.
>>>>
>>>># echo "[2008-02-24 21:07:08.149124] 6451642 196612 547 0 6839170" |
>>>>awk -F
>>>>"[].[]+" 'system("date +%s -d ") $2'
>>>>date: option requires an argument -- d
>>>>Try `date --help' for more information.
>>>>[2008-02-24 21:07:08.149124] 6451642 196612 547 0 6839170
>>>
>>>This seems to be what you're asking for:
>>>
>>>$ echo "[2008-02-24 21:07:08.149124] 6451642 196612 547 0 6839170" |
>>>awk -F "[].[]+" 'system("date +%s -d \"" $2 "\"")'
>>>1203908828
>>>
>>>but I'm sure there's a better way to do whatever it is you're trying to
>>>do
>>>just
>>>using awk instead of jumping back and forth between awk and shell
>>>commands. If
>>>you can show us some sample input and expected out, I expect we could
>>>help.
>>>
>>>Ed.
>>>
>>>
>>>
>> awk -F "[].[]+" 'system("date +%s -d \"" $2 "\"")'
>> --- this is really tricky! People are always confused of those " ' ` $
>> and
>> escaped or unescaped. I still don't know why we need \"" $2 "\"".
>
> It's very simple: whatever command you want to run on your OS, you need
to
> pass
> so the system() command as a string. On your OS, you'd want to run:
>
> date +s -d "date"
>
> so the string you need to pass to system() is:
>
> date +s -d "date"
>
> Since the quotes are the delimiters for the string you pass to system()
> you need
> to surround that thext with quotes and esacpe any quotes used within
that
> string:
>
> "date +s -f \"date\""
>
> Since you're constructing the string to be passed to system() from some
> fixed
> text plus the value of $0, you need to use string concateantion on 3
> string:
>
> "date +s -f \""
> $2
> "\""
>
> so it's:
>
> "date +s -f \"" $2 "\""
>
>> ok, my input is like below:
>>
>> time f1 f2 pid
>> ...
>> [2008-02-24 21:07:08.149124] 6451642 196612 547 0 6839170
>> [2008-02-24 21:07:08.202526] 9330060 196612 555 0 15649568
>> [2008-02-24 21:07:08.358302] 7052812 196612 561 0 11683309
>> [2008-02-24 21:07:08.403536] 8814437 196612 555 0 10075256
>> [2008-02-24 21:07:08.916245] 8315044 196612 550 0 7098662
>> [2008-02-24 21:07:09.247885] 5694065 196612 549 0 10033038
>> [2008-02-24 21:07:09.276933] 9282129 196612 549 0 12066863
>> [2008-02-24 21:07:09.462647] 9794128 196612 449 0 16793249
>> [2008-02-24 21:07:09.476629] 6601802 196612 556 0 15964258
>> [2008-02-24 21:07:09.665840] 9088251 196612 558 0 17974450
>> ...
>>
>> output will be:
>> 1. print the lines which time is between the past 5 minutes and now;
>> 2. count how many lines for each "pid" in the past 5 minutes;
>
> Try this )untested):
>
> awk 'BEGIN{ now=systime(); tgt=5 * 60 * 60 }
> { then=mktime(gensub(/\[(....)-(..)-(..) (..):(..):(..).*/,"\\1 \\2 \\3
> \\4 \\5
> \\6","")) }
> (now - then) > tgt { print; count[$5]++ }
> END{ for (pid in count) print pid,count[pid] }' file
>
> Regards,
>
> Ed.
>
awk 'BEGIN{ now=systime(); tgt=5 * 60 }
{ then=mktime(gensub(/\[(....)-(..)-(..) (..):(..):(..).*/,"\\1 \\2 \\3
\\4
\\5 \\6","")) }
(now - then) < tgt { print; count[$5]++ }
END{ for (pid in count) print pid,count[pid] }' file
This works. In the mean time I use another perl script to get the same
result, but the code is more than awk, and need some perl modules.
A question: how do we use awk to process a very large file (ie. 500000
lines) by reading file from bottom to top?
I know we can use array to reverse a small file, and we can also apply it
on
the big file. However that costs too much, and it is not suitable for a
frequent job.
Best Reards,
DanielC.


|