pocho
pocho

Reputation: 1

how can i tail the last line of multiple log files, only if they have not completed yet?

I have multiple subdirectories, and each has a log file that I want to check, but I only want to check the log files that have not reached the "completed" state. The last line of a completed log file contains the word "completed". These log files could be large (10k+ lines), so I know grep might not be ideal. I want to print the last line of each log file that hasn't completed yet.

find ~+ -iname "log.out" -exec printf '%s\0' {} \; | xargs -0 grep -L completed | xargs tail -n 1

This is what I have so far. This works, but becomes very slow as the number of subdirectories and log files increases. Is there a better way?

Ex:

./test1  
    log.out ------------> "...status:completed:"  
    dummy.txt

./test2  
    log.out ------------> "...status:95%"  
    dummy.txt  

./test3  
    log.out ------------> "...status:93%"  
    dummy.txt  

desired output:

./test2/log.out  
    status:95%
./test3/log.out  
    status:93%

Upvotes: 0

Views: 80

Answers (1)

Ed Morton
Ed Morton

Reputation: 204381

Given the sample input/output now suggested by the updated question, using any POSIX awk:

$ find . -type f -name log.out -exec tail -vn 1 {} + |
    awk '
        ((NR%3) == 2) && !/completed/ {
            gsub(/^==> | <==$/, "", prev)
            print prev ORS "   " $0
        }
        { prev=$0 }
    '
./test2/log.out
   status:95%
./test3/log.out
   status:93%

The above was run on this input:

$ head test*/log.out
==> test1/log.out <==
some
stuff
status:completed:

==> test2/log.out <==
this
status:95%

==> test3/log.out <==
and
partially completed
too
status:93%

Original answer:

Isn't this all you need?

find ~+ -iname "log.out" -exec tail -qn 1 {} + | grep -v completed

It just finds every file, prints the last line of each and then discards those that contain completed. That'll be much faster than what you're currently doing which is to find every file, then call xrags to call grep on every file to print the names of those that don't contain the word "completed", then call xargs again to call tail on each of those files.

Upvotes: 3

Related Questions