Print the lines between two dates from the log using shell command in linux
Another approach with a sed one-liner: sed -n '/start/,/end/p' log.txt
$ cat /tmp/log.txt
before
before
before
a log line containing 02/04/2015:14:23:00 and some other stuff
between
between
a log line containing 02/04/2015:14:23:59 and some other stuff
after
after
$ sed -n '/02\/04\/2015:14:23:00/,/02\/04\/2015:14:23:59/p' /tmp/log.txt
a log line containing 02/04/2015:14:23:00 and some other stuff
between
between
a log line containing 02/04/2015:14:23:59 and some other stuff
Please note it will not work as expected if start and end tokens are in the same line.
logs between two dates i unix
You don't need sed
, you need grep
. Besides that, your query is too overcomplicated, if you need event that happened on 6th, you can only search for 6th:
grep "06 Apr 2014" catalina.logs
If you need to specify wider amount of days, you may use a regular expression to do that, e.g.:
grep "[1-3][0-9] Mar 2014" catalina.logs
will search for all entries from March.
Shell script to extract data from file between two date ranges
It may not have been your first choice but Perl is great for this task.
perl -ne "print if ( m/2013-06-02/ .. m/2013-06-15/ )" myfile.txt
The way this works is that if the first trigger is matched (i.e. m/2013-06-02/
) then the condition (print
) will be executed on each line until the second trigger is matched (i.e. m/2013-06-15
).
However this trick won't work if you specify m/2013-06-01/
as a trigger because this is never matched in your file.
A less exciting technique is to extract some text from each line and test that:
perl -ne 'if ( m/^([0-9-]+)/ ) { $date = $1; print if ( $date ge "2013-06-01" and $date le "2013-06-15" ) }' myfile.txt
(Tested both expressions and working).
Bash script to extract lines between two different timestamps in a log file
Using sed
is good for exact pattern matching, but for comparing values "greater than" or "less than", you might find it easier to use grep
or awk
. For example, given the input (space between date & time, tab separating timestamp from log entry):
$ cat foo.txt
22/06/23 19:30:21 [Logs ... 5]
22/06/24 17:58:30 [Logs ... 4]
22/06/24 17:59:48 [Logs ... 3]
22/06/24 18:11:27 [Logs ... 2]
22/06/24 18:11:28 [Logs ... 1]
you could use sed
as shown in the other answer (which I'll extend to awk
by comparison):
$ sed -n '\#22/06/24 17:58:30#, \#22/06/24 18:11:27#p' foo.txt
22/06/24 17:58:30 [Logs ... 4]
22/06/24 17:59:48 [Logs ... 3]
22/06/24 18:11:27 [Logs ... 2]
It's basically:
$ sed -n '/pattern1/, /pattern2/p' file.txt
Note the tricky part about needing to change the /pattern1/, /pattern2/
to something that would allow slash (/
) in the search pattern. Pick one that's best for your data. I'm using #
here.
Using awk
is about the same, except allowing /
in the search pattern is a little different; so,
$ awk -F'\t' '/pattern1/, /pattern2/' file.txt
becomes, in order to allow /
in the pattern:
$ awk -F'\t' '$0~v1, $0~v2' v1="pattern1" v2="pattern2" file.txt
But this just matches lines between two patterns, and the patterns must match exactly. We could treat the timestamps like alphanumeric patterns, and match lines "greater than" pattern1
up to lines "less than" pattern2
:
$ awk -F'\t' '$1>=v1 && $1<=v2' v1="22/06/24 17:58:30" v2="22/06/24 18:11:27" foo.txt
22/06/24 17:58:30 [Logs ... 4]
22/06/24 17:59:48 [Logs ... 3]
22/06/24 18:11:27 [Logs ... 2]
But it's an alphanumeric comparison, so you can use other dates like search patterns:
$ awk -F'\t' '$1>=v1 && $1<=v2' v1="22/06/24 00:00:00" v2="22/06/24 18:00:00" foo.txt
22/06/24 17:58:30 [Logs ... 4]
22/06/24 17:59:48 [Logs ... 3]
You can switch the >=
and <=
to just simple >
and <
depending on whether you want to include the given date or not.
How to print dates between two dates in format %Y%m%d in shell script?
Using GNU date:
$ d=; n=0; until [ "$d" = "$enddate" ]; do ((n++)); d=$(date -d "$startdate + $n days" +%Y%m%d); echo $d; done
20160513
20160514
Or, spread over multiple lines:
startdate=20160512
enddate=20160514
d=
n=0
until [ "$d" = "$enddate" ]
do
((n++))
d=$(date -d "$startdate + $n days" +%Y%m%d)
echo $d
done
How it works
d=; n=0
Initialize variables.
until [ "$d" = "$enddate" ]; do
Start a loop that ends on
enddate
.((n++))
Increment the day counter.
d=$(date -d "$startdate + $n days" +%Y%m%d)
Compute the date for
n
days afterstartdate
.echo $d
Display the date.
done
Signal the end of the loop.
Read the log files and get the entries between two dates
The link you quoted would be used if you know 2 specific strings that appear in your log file. That command will search for the first string and display all lines until it finds the second string and then stops.
In your case, if you want generic date manipulation, you might be better off with perl
and one of the date/time modules. Most (if not all) of those have built-in date comparison routines, and many of them will take the date in almost any format imaginable ... and the ones that don't typically provide the ability to specify the date format.
(If you're just using dates and not using times, then Date::EzDate is my favorite, and probably the easiest to learn and implement quickly.)
Shell commands are probably not going to do a good job of date manipulation.
How to search for lines in a file between two timestamps using Bash
I believe sed is the best option:
sed -rne '/<timestamp>/,/<timestamp>/ p' <file>
ex:
tiago@dell:~$ sed -rne '/08:17:38/,/08:24:36/ p' /var/log/syslog
May 16 08:17:38 dell AptDaemon.Worker: INFO: Processing transaction /org/debian/apt/transaction/08a244f7b8ce4fad9f6b304aca9eae7a
May 16 08:17:50 dell AptDaemon.Worker: INFO: Finished transaction /org/debian/apt/transaction/08a244f7b8ce4fad9f6b304aca9eae7a
May 16 08:18:50 dell AptDaemon.PackageKit: INFO: Initializing PackageKit transaction
May 16 08:18:50 dell AptDaemon.Worker: INFO: Simulating trans: /org/debian/apt/transaction/37c3ef54a6ba4933a561c49b3fac5f6e
May 16 08:18:50 dell AptDaemon.Worker: INFO: Processing transaction /org/debian/apt/transaction/37c3ef54a6ba4933a561c49b3fac5f6e
May 16 08:18:51 dell AptDaemon.PackageKit: INFO: Get updates()
May 16 08:18:52 dell AptDaemon.Worker: INFO: Finished transaction /org/debian/apt/transaction/37c3ef54a6ba4933a561c49b3fac5f6e
May 16 08:24:36 dell AptDaemon: INFO: Quitting due to inactivity
Print all the lines between two patterns in shell
I think you can use the awk
command as followed to print the lines between Aug 19
& Aug 20
,
awk '/Aug 19/||/Aug 20/{a++}a; a==4{a=0}' file
Brief explanation,
/Aug 19/||/Aug 20/
: find the record matchedAug 19
orAug 20
- if the criteria is met, set the flag
a++
- if the flag
a
in front of the semicolon is greater than 0, that would print the record. - Final criteria, if
a==4
, then reseta=0
, mind that it only worked for the case in the example, ifAug 19
orAug 20
are more than 4, modify the number 4 in the answer to meet your new request.
If you want to assign the searched patterns into variables, modify the command as followed,
$ b="Aug 19"
$ c="Aug 20"
$ awk -v b="$b" -v c="$c" '$0 ~ c||$0 ~ b{a++}a; a==4{a=0}' file
Related Topics
How to Delete 5 Lines Before and 6 Lines After Pattern Match Using Sed
Can't Install Using Yum in Rhel 7.1
How to Install and Run Tacotron2 on Ubuntu Wsl
Removing File from Folder in Linux
Linux Configuration - Ssmtp: Cannot Open Smtp.Gmail.Com:587
Why Does 'Ping' Not Timeout in Linux
Detecting If The Monitor Is Powered Off
How to Restrict Access to Certain Files for a Certain Process
Where Is The Linux Socket Implementation
Git Error: Cannot Handle Https
Is There a Rpm File Naming Convention in Lsb
How to Make Linux Ignore a Keyboard While Keeping It Available for My Program to Read
Linux Usb Driver Probe Not Called If Device Already Plugged
Difference Between $() and () in Bash
How to Find The Version of a Compiled Kernel Module
Library Path Order for Alternate Glibc Dynamic Linker (Ld.So)