Olly
Olly

Reputation: 7758

Can you grep a file using a regular expression and only output the matching part of a line?

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

Answers (9)

Raja Ravindra
Raja Ravindra

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

Mikhail V.
Mikhail V.

Reputation: 75

-r option for sed allows regexps without backslashes

sed -n -r 's/Failed to add (.*) to database/\1/p' filename

Upvotes: 1

Valentin
Valentin

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

bortzmeyer
bortzmeyer

Reputation: 35459

Recent versions of GNU grep have a -o option which does exactly what you want. (-o is for --only-matching).

Upvotes: 5

RandomNickName42
RandomNickName42

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

Noldorin
Noldorin

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

SpliFF
SpliFF

Reputation: 38956

or python:

cat file | python -c "import re, sys; print '\r\n'.join(re.findall('add (.*?) to', sys.stdin.read()))"

Upvotes: 1

Maciej Łebkowski
Maciej Łebkowski

Reputation: 3887

sed is fine without grep:

sed -n 's/Failed to add \(.*\) to database/\1/p' filename

Upvotes: 15

Nathan Fellman
Nathan Fellman

Reputation: 127428

You can use sed:

grep -E 'Failed to add (.*) to database'| sed 's/'Failed to add \(.*\) to database'/\1'

Upvotes: 5

Related Questions