Reputation: 1
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
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