Pascoe
Pascoe

Reputation: 177

Sed extract section of log file with timestamp boundaries

I have a selection of log files containing amongst other things time stamps.

Fwiw format is YYYY-MM-DD HH:MM:SS.sss (ie milliseconds granularity but no further)

Happily for me I can reasonably expect these timestamps to be both sorted chronologically AND unique.

However I am running into issues extracting the portion of the log file falling between two timestamps.

first timestamp in my file is 21:27:57.545 last timestamp in my file is 21:28:45.631

Syntax I am using is e.g.

sed -n '/21:28:10*/,/21:28:22*/p'

This is yielding some odd results (I am sure user error)

start time of 21:28:10* gives me timestamps starting at 21:28:10.043 (so far so good as prior was 21:28:09.484 so it is starting in the right place)

however start time of 21:28:09* gives me timestamps starting at 21:28:00.003

end time equally odd. end time of 21:28:22* yields timestamps up to and including 21:28:20.050, however I know for a fact that there timestamps after that as follows;

2017-05-10 21:28:21.278, 901
2017-05-10 21:28:21.303, 901
2017-05-10 21:28:21.304, 901
2017-05-10 21:28:21.483, 901
2017-05-10 21:28:22.448, 901

Therefore I am wondering if this is something to do with how sed interprets the strings - is it as text? Is there a one liner way to do what I am trying to do? Ideally I would be able to specify the start and end timestamps down to the same granularity as the actual data (ie in this case milliseconds)

TIA

Upvotes: 1

Views: 1610

Answers (2)

Wayne Vosberg
Wayne Vosberg

Reputation: 1053

If you want to get really crazy:

#!/bin/bash
T1="$(date -d '2017-05-10 21:28:21' +'%s').300" # your start time
T2="$(date -d '2017-05-10 21:28:21' +'%s').400" # your end time
while read L 
do 
    D="$(echo $L | cut -c1-19)" # assuming line starts with timestamp
    T=$(date -d "$D" +'%s')
    T="${T}.$(echo $L | cut -c21-23)" 
    if [ $(echo $T'>'$T1 | bc -l) == 1 ] && [ $(echo $T'<'$T2 | bc -l) == 1 ]
    then
        echo "HIT: $L"
    else
        echo "NO!: $L"
    fi
done < your_log_file

Upvotes: 0

pynexj
pynexj

Reputation: 20698

You should use .* instead of *.

The RE 21:28:10* would match strings starting with 21:28:1 which can be followed by zero or more 0 chars.

Upvotes: 1

Related Questions