blindside044
blindside044

Reputation: 456

Linux: grep for multiple strings in a log file on a certain date

Sorry for a seemingly frequently asked question, but the other thread answers did not work for me. The log I am trying to search through is formatted like so:

Jul 24 23:11:08 TG-12345 gateway [words] Tools 987654321 Join request

I want to grep the log found in /var/etc/messages for all instances of the date, let's say 'Jul 24' in this case, and '987654321'. What is the proper instruction to do this? Thank you.

EDIT: though not necessary, if you know how to also throw in a timeframe (the hour, not the date) in the same search, that would be great; but I do need at least the date and tool# working first. Thanks again.

Upvotes: 2

Views: 7795

Answers (5)

RavinderSingh13
RavinderSingh13

Reputation: 133458

try with awk also.

awk '/Jul 24/ && /987654321/' Input_file

Explanation: Looking for string "Jul 24" and number "987654321" on a single line, so && condition will make sure it have them both on a single line. If they are present on a single line then it will print that line(Though print is NOT written here but awk works on method of condition/action and when NO action is present then it will print line by default).

Upvotes: 0

diz
diz

Reputation: 275

grep 'Jul 24.*987654321' /var/log/messages

The secret here is the use of the metacharacter . that means "any character" and the quantifier * meaning "0 or more". For more information on other metacharacters, read up on regular expressions.

For timeframes, you can use ranges. This would get everything from July 10 through July 29 containing 987654321 --

grep 'Jul [12].*987654321' /var/log/messages

Anything more complex than that will need to involve arithmetic comparisons instead of pattern matching. I often use awk for this. For example, this will get everything containing 987654321 from June 12 to June 18 and from July 20 through July 25 out of every compressed and uncompressed messages log file --

zcat -f /var/log/messages* | grep 987654321 | awk '($1 == "Jun" && $2 >= 12 && $3 <= 18) || ($1 == "Jul" && $2 >= 20 && $3 <= 25)'

Upvotes: 0

gpojd
gpojd

Reputation: 23065

I usually just do this:

grep 'Jul 24' /var/etc/messages | grep 987654321

Upvotes: 0

randomir
randomir

Reputation: 18687

To search over a range, you can use sed, like this:

sed -n '/Jul 24/,/Jul 27/p' file

this will print all lines between (and including) the lines that contain Jul 24 and Jul 27. The -n flag suppresses output not explicitly printed (here with p command). The /pattern1/,/pattern2/ is a regex address with which we select all lines between the first and the second pattern (in this case a literal string).

This is not limited to dates, you can specify hours/minutes/etc:

sed -n '/Jul 24 22:/,/Jul 24 23:/p' file

Just be sure the patterns appear in the file, or otherwise sed won't be able to match the start/end of your block (since it's literal matching, not actual date range matching). For example, if you are too specific on the end pattern, like Jul 24 23:59:59, and that value actually never appears in the file, sed will happily keep printing until the end of the file.

After you're done with sed "preselection", you can then just grep that output for your other pattern, like this:

sed -n '/Jul 24/,/Jul 27/p' file | grep 987654321

Actually, you could do it with a single sed command:

sed -n '/Jul 24/,/Jul 27/ { /987654321/p }' file

if so you wish.

Upvotes: 2

Ben
Ben

Reputation: 6348

Just use the command twice:

grep 'Jul 24' <filename> | grep '987654321'

Upvotes: 4

Related Questions