Reputation: 456
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
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
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
Reputation: 23065
I usually just do this:
grep 'Jul 24' /var/etc/messages | grep 987654321
Upvotes: 0
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
Reputation: 6348
Just use the command twice:
grep 'Jul 24' <filename> | grep '987654321'
Upvotes: 4