Take the 2-minute tour ×

I know there are many examples of a non-greedy regex with grep, but I'm having problems with my specific case.

My file contains lines similar to:


and I'm trying to parse out just the X12345 part.
That is, the part starting with X and up until the first period (.)

My closest example so far is:

grep -Eo "X(.*?)\."  inputfile

But that is too greedy (even though I think I used .*? properly.

Can someone help guide me to a proper regex?

share|improve this question
why grep ? This sounds like a job for cut -d '.' -f1 | cut -d '[' -f2, to me. –  Sirex Aug 9 '12 at 0:14

1 Answer 1

up vote 2 down vote accepted

You are using .* properly but as you noticed it is greedily eating up as many characters as it can in your match because . matches any character. You could do:

grep -Eo "X([^.]*?)\." inputFile

This matches an X followed by any length sequence of any non dot ([^.]*) up to some character (?) and a dot (\.). You say you are interested in everything between the first X and the first . though, so you could simplify this further:

grep -Eo "X[^.]*\." inputFile
share|improve this answer
That makes some sense. If I know what follows X will only be digits, does this expression work? "X[0-9]+\." (I'll try all this when I get to the office tomorrow) –  abelenky Aug 9 '12 at 4:15
yes, that would also work. Generally the more restrictive your match the better. Just as an aside I hadn't seen the -o switch used with grep before (learn something every day!). Usually I'd use sed for something like this. In sed would have looked like this: sed -E 's/^.*(X[^.]*\.).*$/\1/' inputFile. –  dsummersl Aug 9 '12 at 12:13
Thanks. Any particular reason for the preference of sed -E over grep -Eo? –  abelenky Aug 9 '12 at 17:33
Habit, honestly. That said, you can accomplish more with sed than grep. It searches/replaces for single lines as well across multiple lines of your input. Suppose you wanted to filter all of the 'foobar' patterns in a file and then transpose foo with bar (barfoo). You could do that with sed, but not grep: sed -E 's/(foo)(bar)/\2\1/' inputFile –  dsummersl Aug 9 '12 at 18:32
It seems there is an important difference in how they operate: sed allows everything through, processing only what matches. grep blocks everything, allowing through only what matches. –  abelenky Aug 9 '12 at 19:33

Your Answer


