Reputation: 7758
I have a log file which contains a number of error lines, such as:
Failed to add [email protected] to database
I can filter these lines with a single grep call:
grep -E 'Failed to add (.*) to database'
This works fine, but what I'd really like to do is have grep (or another Unix command I pass the output into) only output the email address part of the matched line.
Is this possible?
Upvotes: 15
Views: 24685
Reputation: 313
If you just want to use grep and output only matching part of line
grep -E -o 'Failed to add (.*) to database'
Then maybe if you want to write it to a file
cat yourlogfile | grep -E -o 'Failed to add (.*) to database' >> outputfile
So as of grep utility -o
is going to -o, --only-matching show only nonempty parts of lines that match'
.
Upvotes: 0
Reputation: 75
-r
option for sed
allows regexps without backslashes
sed -n -r 's/Failed to add (.*) to database/\1/p' filename
Upvotes: 1
Reputation: 426
You can also just pipe grep to itself :)
grep -E 'Failed to add (.*) to database' | grep -Eo "[^ ]+@[^ ]+"
Or, if "lines in interest" are the only ones with emails, just use the last grep command without the first one.
Upvotes: 8
Reputation: 35459
Recent versions of GNU grep have a -o
option which does exactly what you want. (-o
is for --only-matching
).
Upvotes: 5
Reputation: 5955
If you want to use grep, it would be more appropiate to use egrep;
About egrep
Search a file for a pattern using full regular expressions.
grep will not always have as complete of functionality for regex.
Upvotes: -2
Reputation: 147240
This should do the job:
grep -x -e '(?<=Failed to add ).+?(?= to database)'
It uses a positive look-ahead assertion, followed by the match for the email address, followed by a postivie look-behind assertion. This insures that it matches the entire line, but only actually consumes (and thus returns) the email address part.
The -x
option specifies that grep should match lines rather than the whole text.
Upvotes: 2
Reputation: 38956
or python:
cat file | python -c "import re, sys; print '\r\n'.join(re.findall('add (.*?) to', sys.stdin.read()))"
Upvotes: 1
Reputation: 3887
sed
is fine without grep:
sed -n 's/Failed to add \(.*\) to database/\1/p' filename
Upvotes: 15
Reputation: 127428
You can use sed:
grep -E 'Failed to add (.*) to database'| sed 's/'Failed to add \(.*\) to database'/\1'
Upvotes: 5