Average of last n matches using awk

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
0
down vote

favorite












I have a growing file. while will write the log of my application process. In that file, there is a log for "speed" as below



(some text)
speed= 1x
(some text)
speed= 1x
(some text)
speed= 1x
(some text)
speed= 0.9x
..
..
(some text)
speed= 0.8x
(some text)


I have tried the below code to get the average value of speed.



 awk '/speed/ gsub("x","");print $2' $PROCESS_LOG_FILE | awk -F : 'sum+=$1 END print sum/NR'


is it possible to get the average of the last 120 entries? I have tried with grep and tail, but it took a long time since its a growing file.










share|improve this question





















  • Now, "last 120" with a "growing file" might be a bit difficult to catch... you may need to define a point in time that you start the data collection.
    – RudiC
    Nov 19 at 15:22










  • @RudiC Yes....finally, I end up with tail -n120 between 2 awks
    – msp9011
    Nov 19 at 15:24










  • I tought you were going for a tail -f some.log | awk '...'
    – Archemar
    Nov 19 at 15:25














up vote
0
down vote

favorite












I have a growing file. while will write the log of my application process. In that file, there is a log for "speed" as below



(some text)
speed= 1x
(some text)
speed= 1x
(some text)
speed= 1x
(some text)
speed= 0.9x
..
..
(some text)
speed= 0.8x
(some text)


I have tried the below code to get the average value of speed.



 awk '/speed/ gsub("x","");print $2' $PROCESS_LOG_FILE | awk -F : 'sum+=$1 END print sum/NR'


is it possible to get the average of the last 120 entries? I have tried with grep and tail, but it took a long time since its a growing file.










share|improve this question





















  • Now, "last 120" with a "growing file" might be a bit difficult to catch... you may need to define a point in time that you start the data collection.
    – RudiC
    Nov 19 at 15:22










  • @RudiC Yes....finally, I end up with tail -n120 between 2 awks
    – msp9011
    Nov 19 at 15:24










  • I tought you were going for a tail -f some.log | awk '...'
    – Archemar
    Nov 19 at 15:25












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I have a growing file. while will write the log of my application process. In that file, there is a log for "speed" as below



(some text)
speed= 1x
(some text)
speed= 1x
(some text)
speed= 1x
(some text)
speed= 0.9x
..
..
(some text)
speed= 0.8x
(some text)


I have tried the below code to get the average value of speed.



 awk '/speed/ gsub("x","");print $2' $PROCESS_LOG_FILE | awk -F : 'sum+=$1 END print sum/NR'


is it possible to get the average of the last 120 entries? I have tried with grep and tail, but it took a long time since its a growing file.










share|improve this question













I have a growing file. while will write the log of my application process. In that file, there is a log for "speed" as below



(some text)
speed= 1x
(some text)
speed= 1x
(some text)
speed= 1x
(some text)
speed= 0.9x
..
..
(some text)
speed= 0.8x
(some text)


I have tried the below code to get the average value of speed.



 awk '/speed/ gsub("x","");print $2' $PROCESS_LOG_FILE | awk -F : 'sum+=$1 END print sum/NR'


is it possible to get the average of the last 120 entries? I have tried with grep and tail, but it took a long time since its a growing file.







linux awk






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 19 at 14:56









msp9011

3,58043862




3,58043862











  • Now, "last 120" with a "growing file" might be a bit difficult to catch... you may need to define a point in time that you start the data collection.
    – RudiC
    Nov 19 at 15:22










  • @RudiC Yes....finally, I end up with tail -n120 between 2 awks
    – msp9011
    Nov 19 at 15:24










  • I tought you were going for a tail -f some.log | awk '...'
    – Archemar
    Nov 19 at 15:25
















  • Now, "last 120" with a "growing file" might be a bit difficult to catch... you may need to define a point in time that you start the data collection.
    – RudiC
    Nov 19 at 15:22










  • @RudiC Yes....finally, I end up with tail -n120 between 2 awks
    – msp9011
    Nov 19 at 15:24










  • I tought you were going for a tail -f some.log | awk '...'
    – Archemar
    Nov 19 at 15:25















Now, "last 120" with a "growing file" might be a bit difficult to catch... you may need to define a point in time that you start the data collection.
– RudiC
Nov 19 at 15:22




Now, "last 120" with a "growing file" might be a bit difficult to catch... you may need to define a point in time that you start the data collection.
– RudiC
Nov 19 at 15:22












@RudiC Yes....finally, I end up with tail -n120 between 2 awks
– msp9011
Nov 19 at 15:24




@RudiC Yes....finally, I end up with tail -n120 between 2 awks
– msp9011
Nov 19 at 15:24












I tought you were going for a tail -f some.log | awk '...'
– Archemar
Nov 19 at 15:25




I tought you were going for a tail -f some.log | awk '...'
– Archemar
Nov 19 at 15:25










4 Answers
4






active

oldest

votes

















up vote
2
down vote













A bit far fetched, maybe, but as tac will lseek the momentary file end, you'd define the necessary point in time, and from there go backwards until 120 speeds encountered:



tac file | awk '/speed/ SUM += $2; if (++C == 120) print SUM/C; exit'


Or to handle inputs that might have fewer than 120 occurrences of the pattern:



tac file | awk '/speed/ SUM += $2; if (++C == 120) exit
END if (C) print SUM/C'





share|improve this answer






















  • @ Stéphane Chazelas: I was transiently thinking of that as well but didn't get at your reasoning. Thanks!
    – RudiC
    Nov 19 at 15:49


















up vote
1
down vote













I'd use perl rather than awk for this: quite straightforward to remember just the last 120 speeds:



perl -MList::Util=sum -nE '
if (/speed= ([d.]+)/) @speeds = ($1, @speeds)[0..119]
# could also write:
# if (/speed= ([d.]+)/) push @speeds, $1; shift @speeds if @speeds > 120

END say @speeds == 0 ? "No matches" : sum(@speeds)/@speeds
' speed.log





share|improve this answer






















  • got an error as Illegal division by zero at -e line 1, <> line 5700. END failed--call queue aborted, <> line 5700.
    – msp9011
    Nov 19 at 15:29










  • Hmm, sounds like that regex has found no matches.
    – glenn jackman
    Nov 19 at 15:35

















up vote
0
down vote













You'll have to use a circular table, here is a sample code with last 5 values



BEGIN maxi=5 ; c=0 ; nb=0 ; 
/^speed/ list[nb++]=$2 ; nb=nb % maxi ;
c++ ; if (c> maxi) c=maxi ;
s=0 ;
for(i=0;i<=c;i++) s+=list[i] ;
printf "NR: %d, c=%d, s=%d AVG : %3.2fn",NR,c,s,s/c ;



you can test on a sample file (or on command line, values to be entered on command line).



awk -f avg.awk sample.txt


then replace 5 by 120, and printf line by what suit you.



note that +=$2 will ignore trailling x.






share|improve this answer



























    up vote
    0
    down vote













    Does this work for you?



    grep speed test | tail -n 120 | cut -d " " -f 2 | cut -d "x" -f 1 | awk -F : 'sum+=$1 END print sum/NR'



    I just put your input into a file called test and ran that. Output:



    0.94



    Can't tell what performance will be on a huge file, though.






    share|improve this answer






















    • your first 3 pips will do similar as awk '/speed/ gsub("x","");print $2'
      – msp9011
      Nov 19 at 15:04










    • i would like to know is there any way to get the last n matches using awk
      – msp9011
      Nov 19 at 15:05










    • Oh yeah, I forgot to add that. Just pipe the output of grep into tail -n 120
      – Panki
      Nov 19 at 15:23










    • it throws me an error Binary file progress.log matches
      – msp9011
      Nov 19 at 15:26










    Your Answer








    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "106"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f482778%2faverage-of-last-n-matches-using-awk%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote













    A bit far fetched, maybe, but as tac will lseek the momentary file end, you'd define the necessary point in time, and from there go backwards until 120 speeds encountered:



    tac file | awk '/speed/ SUM += $2; if (++C == 120) print SUM/C; exit'


    Or to handle inputs that might have fewer than 120 occurrences of the pattern:



    tac file | awk '/speed/ SUM += $2; if (++C == 120) exit
    END if (C) print SUM/C'





    share|improve this answer






















    • @ Stéphane Chazelas: I was transiently thinking of that as well but didn't get at your reasoning. Thanks!
      – RudiC
      Nov 19 at 15:49















    up vote
    2
    down vote













    A bit far fetched, maybe, but as tac will lseek the momentary file end, you'd define the necessary point in time, and from there go backwards until 120 speeds encountered:



    tac file | awk '/speed/ SUM += $2; if (++C == 120) print SUM/C; exit'


    Or to handle inputs that might have fewer than 120 occurrences of the pattern:



    tac file | awk '/speed/ SUM += $2; if (++C == 120) exit
    END if (C) print SUM/C'





    share|improve this answer






















    • @ Stéphane Chazelas: I was transiently thinking of that as well but didn't get at your reasoning. Thanks!
      – RudiC
      Nov 19 at 15:49













    up vote
    2
    down vote










    up vote
    2
    down vote









    A bit far fetched, maybe, but as tac will lseek the momentary file end, you'd define the necessary point in time, and from there go backwards until 120 speeds encountered:



    tac file | awk '/speed/ SUM += $2; if (++C == 120) print SUM/C; exit'


    Or to handle inputs that might have fewer than 120 occurrences of the pattern:



    tac file | awk '/speed/ SUM += $2; if (++C == 120) exit
    END if (C) print SUM/C'





    share|improve this answer














    A bit far fetched, maybe, but as tac will lseek the momentary file end, you'd define the necessary point in time, and from there go backwards until 120 speeds encountered:



    tac file | awk '/speed/ SUM += $2; if (++C == 120) print SUM/C; exit'


    Or to handle inputs that might have fewer than 120 occurrences of the pattern:



    tac file | awk '/speed/ SUM += $2; if (++C == 120) exit
    END if (C) print SUM/C'






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 20 at 6:27









    Stéphane Chazelas

    294k54554897




    294k54554897










    answered Nov 19 at 15:34









    RudiC

    3,1861211




    3,1861211











    • @ Stéphane Chazelas: I was transiently thinking of that as well but didn't get at your reasoning. Thanks!
      – RudiC
      Nov 19 at 15:49

















    • @ Stéphane Chazelas: I was transiently thinking of that as well but didn't get at your reasoning. Thanks!
      – RudiC
      Nov 19 at 15:49
















    @ Stéphane Chazelas: I was transiently thinking of that as well but didn't get at your reasoning. Thanks!
    – RudiC
    Nov 19 at 15:49





    @ Stéphane Chazelas: I was transiently thinking of that as well but didn't get at your reasoning. Thanks!
    – RudiC
    Nov 19 at 15:49













    up vote
    1
    down vote













    I'd use perl rather than awk for this: quite straightforward to remember just the last 120 speeds:



    perl -MList::Util=sum -nE '
    if (/speed= ([d.]+)/) @speeds = ($1, @speeds)[0..119]
    # could also write:
    # if (/speed= ([d.]+)/) push @speeds, $1; shift @speeds if @speeds > 120

    END say @speeds == 0 ? "No matches" : sum(@speeds)/@speeds
    ' speed.log





    share|improve this answer






















    • got an error as Illegal division by zero at -e line 1, <> line 5700. END failed--call queue aborted, <> line 5700.
      – msp9011
      Nov 19 at 15:29










    • Hmm, sounds like that regex has found no matches.
      – glenn jackman
      Nov 19 at 15:35














    up vote
    1
    down vote













    I'd use perl rather than awk for this: quite straightforward to remember just the last 120 speeds:



    perl -MList::Util=sum -nE '
    if (/speed= ([d.]+)/) @speeds = ($1, @speeds)[0..119]
    # could also write:
    # if (/speed= ([d.]+)/) push @speeds, $1; shift @speeds if @speeds > 120

    END say @speeds == 0 ? "No matches" : sum(@speeds)/@speeds
    ' speed.log





    share|improve this answer






















    • got an error as Illegal division by zero at -e line 1, <> line 5700. END failed--call queue aborted, <> line 5700.
      – msp9011
      Nov 19 at 15:29










    • Hmm, sounds like that regex has found no matches.
      – glenn jackman
      Nov 19 at 15:35












    up vote
    1
    down vote










    up vote
    1
    down vote









    I'd use perl rather than awk for this: quite straightforward to remember just the last 120 speeds:



    perl -MList::Util=sum -nE '
    if (/speed= ([d.]+)/) @speeds = ($1, @speeds)[0..119]
    # could also write:
    # if (/speed= ([d.]+)/) push @speeds, $1; shift @speeds if @speeds > 120

    END say @speeds == 0 ? "No matches" : sum(@speeds)/@speeds
    ' speed.log





    share|improve this answer














    I'd use perl rather than awk for this: quite straightforward to remember just the last 120 speeds:



    perl -MList::Util=sum -nE '
    if (/speed= ([d.]+)/) @speeds = ($1, @speeds)[0..119]
    # could also write:
    # if (/speed= ([d.]+)/) push @speeds, $1; shift @speeds if @speeds > 120

    END say @speeds == 0 ? "No matches" : sum(@speeds)/@speeds
    ' speed.log






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 19 at 19:02

























    answered Nov 19 at 15:19









    glenn jackman

    49.4k469106




    49.4k469106











    • got an error as Illegal division by zero at -e line 1, <> line 5700. END failed--call queue aborted, <> line 5700.
      – msp9011
      Nov 19 at 15:29










    • Hmm, sounds like that regex has found no matches.
      – glenn jackman
      Nov 19 at 15:35
















    • got an error as Illegal division by zero at -e line 1, <> line 5700. END failed--call queue aborted, <> line 5700.
      – msp9011
      Nov 19 at 15:29










    • Hmm, sounds like that regex has found no matches.
      – glenn jackman
      Nov 19 at 15:35















    got an error as Illegal division by zero at -e line 1, <> line 5700. END failed--call queue aborted, <> line 5700.
    – msp9011
    Nov 19 at 15:29




    got an error as Illegal division by zero at -e line 1, <> line 5700. END failed--call queue aborted, <> line 5700.
    – msp9011
    Nov 19 at 15:29












    Hmm, sounds like that regex has found no matches.
    – glenn jackman
    Nov 19 at 15:35




    Hmm, sounds like that regex has found no matches.
    – glenn jackman
    Nov 19 at 15:35










    up vote
    0
    down vote













    You'll have to use a circular table, here is a sample code with last 5 values



    BEGIN maxi=5 ; c=0 ; nb=0 ; 
    /^speed/ list[nb++]=$2 ; nb=nb % maxi ;
    c++ ; if (c> maxi) c=maxi ;
    s=0 ;
    for(i=0;i<=c;i++) s+=list[i] ;
    printf "NR: %d, c=%d, s=%d AVG : %3.2fn",NR,c,s,s/c ;



    you can test on a sample file (or on command line, values to be entered on command line).



    awk -f avg.awk sample.txt


    then replace 5 by 120, and printf line by what suit you.



    note that +=$2 will ignore trailling x.






    share|improve this answer
























      up vote
      0
      down vote













      You'll have to use a circular table, here is a sample code with last 5 values



      BEGIN maxi=5 ; c=0 ; nb=0 ; 
      /^speed/ list[nb++]=$2 ; nb=nb % maxi ;
      c++ ; if (c> maxi) c=maxi ;
      s=0 ;
      for(i=0;i<=c;i++) s+=list[i] ;
      printf "NR: %d, c=%d, s=%d AVG : %3.2fn",NR,c,s,s/c ;



      you can test on a sample file (or on command line, values to be entered on command line).



      awk -f avg.awk sample.txt


      then replace 5 by 120, and printf line by what suit you.



      note that +=$2 will ignore trailling x.






      share|improve this answer






















        up vote
        0
        down vote










        up vote
        0
        down vote









        You'll have to use a circular table, here is a sample code with last 5 values



        BEGIN maxi=5 ; c=0 ; nb=0 ; 
        /^speed/ list[nb++]=$2 ; nb=nb % maxi ;
        c++ ; if (c> maxi) c=maxi ;
        s=0 ;
        for(i=0;i<=c;i++) s+=list[i] ;
        printf "NR: %d, c=%d, s=%d AVG : %3.2fn",NR,c,s,s/c ;



        you can test on a sample file (or on command line, values to be entered on command line).



        awk -f avg.awk sample.txt


        then replace 5 by 120, and printf line by what suit you.



        note that +=$2 will ignore trailling x.






        share|improve this answer












        You'll have to use a circular table, here is a sample code with last 5 values



        BEGIN maxi=5 ; c=0 ; nb=0 ; 
        /^speed/ list[nb++]=$2 ; nb=nb % maxi ;
        c++ ; if (c> maxi) c=maxi ;
        s=0 ;
        for(i=0;i<=c;i++) s+=list[i] ;
        printf "NR: %d, c=%d, s=%d AVG : %3.2fn",NR,c,s,s/c ;



        you can test on a sample file (or on command line, values to be entered on command line).



        awk -f avg.awk sample.txt


        then replace 5 by 120, and printf line by what suit you.



        note that +=$2 will ignore trailling x.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 19 at 15:10









        Archemar

        19.4k93468




        19.4k93468




















            up vote
            0
            down vote













            Does this work for you?



            grep speed test | tail -n 120 | cut -d " " -f 2 | cut -d "x" -f 1 | awk -F : 'sum+=$1 END print sum/NR'



            I just put your input into a file called test and ran that. Output:



            0.94



            Can't tell what performance will be on a huge file, though.






            share|improve this answer






















            • your first 3 pips will do similar as awk '/speed/ gsub("x","");print $2'
              – msp9011
              Nov 19 at 15:04










            • i would like to know is there any way to get the last n matches using awk
              – msp9011
              Nov 19 at 15:05










            • Oh yeah, I forgot to add that. Just pipe the output of grep into tail -n 120
              – Panki
              Nov 19 at 15:23










            • it throws me an error Binary file progress.log matches
              – msp9011
              Nov 19 at 15:26














            up vote
            0
            down vote













            Does this work for you?



            grep speed test | tail -n 120 | cut -d " " -f 2 | cut -d "x" -f 1 | awk -F : 'sum+=$1 END print sum/NR'



            I just put your input into a file called test and ran that. Output:



            0.94



            Can't tell what performance will be on a huge file, though.






            share|improve this answer






















            • your first 3 pips will do similar as awk '/speed/ gsub("x","");print $2'
              – msp9011
              Nov 19 at 15:04










            • i would like to know is there any way to get the last n matches using awk
              – msp9011
              Nov 19 at 15:05










            • Oh yeah, I forgot to add that. Just pipe the output of grep into tail -n 120
              – Panki
              Nov 19 at 15:23










            • it throws me an error Binary file progress.log matches
              – msp9011
              Nov 19 at 15:26












            up vote
            0
            down vote










            up vote
            0
            down vote









            Does this work for you?



            grep speed test | tail -n 120 | cut -d " " -f 2 | cut -d "x" -f 1 | awk -F : 'sum+=$1 END print sum/NR'



            I just put your input into a file called test and ran that. Output:



            0.94



            Can't tell what performance will be on a huge file, though.






            share|improve this answer














            Does this work for you?



            grep speed test | tail -n 120 | cut -d " " -f 2 | cut -d "x" -f 1 | awk -F : 'sum+=$1 END print sum/NR'



            I just put your input into a file called test and ran that. Output:



            0.94



            Can't tell what performance will be on a huge file, though.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 19 at 15:23

























            answered Nov 19 at 15:00









            Panki

            42719




            42719











            • your first 3 pips will do similar as awk '/speed/ gsub("x","");print $2'
              – msp9011
              Nov 19 at 15:04










            • i would like to know is there any way to get the last n matches using awk
              – msp9011
              Nov 19 at 15:05










            • Oh yeah, I forgot to add that. Just pipe the output of grep into tail -n 120
              – Panki
              Nov 19 at 15:23










            • it throws me an error Binary file progress.log matches
              – msp9011
              Nov 19 at 15:26
















            • your first 3 pips will do similar as awk '/speed/ gsub("x","");print $2'
              – msp9011
              Nov 19 at 15:04










            • i would like to know is there any way to get the last n matches using awk
              – msp9011
              Nov 19 at 15:05










            • Oh yeah, I forgot to add that. Just pipe the output of grep into tail -n 120
              – Panki
              Nov 19 at 15:23










            • it throws me an error Binary file progress.log matches
              – msp9011
              Nov 19 at 15:26















            your first 3 pips will do similar as awk '/speed/ gsub("x","");print $2'
            – msp9011
            Nov 19 at 15:04




            your first 3 pips will do similar as awk '/speed/ gsub("x","");print $2'
            – msp9011
            Nov 19 at 15:04












            i would like to know is there any way to get the last n matches using awk
            – msp9011
            Nov 19 at 15:05




            i would like to know is there any way to get the last n matches using awk
            – msp9011
            Nov 19 at 15:05












            Oh yeah, I forgot to add that. Just pipe the output of grep into tail -n 120
            – Panki
            Nov 19 at 15:23




            Oh yeah, I forgot to add that. Just pipe the output of grep into tail -n 120
            – Panki
            Nov 19 at 15:23












            it throws me an error Binary file progress.log matches
            – msp9011
            Nov 19 at 15:26




            it throws me an error Binary file progress.log matches
            – msp9011
            Nov 19 at 15:26

















             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f482778%2faverage-of-last-n-matches-using-awk%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown






            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Displaying single band from multi-band raster using QGIS

            How many registers does an x86_64 CPU actually have?