I have a file test.txt
, in which there are some formatted phone numbers. I'm trying to use grep
to find the lines containing a phone number.
It seems that grep -e "[0-9]{3}-[0-9]{3}-[0-9]{4}" test.txt
doesn't work and gives no results. But grep -E "[0-9]{3}-[0-9]{3}-[0-9]{4}" test.txt
works. So I wonder what's the difference between these 2 options.
According to man grep
:
-E, --extended-regexp Interpret pattern as an extended regular expression (i.e. force grep to behave as egrep).
-e pattern, --regexp=pattern Specify a pattern used during the search of the input: an input line is selected if it matches any of the specified patterns. This option is most useful when multiple -e options are used to specify multiple patterns, or when a pattern begins with a dash (`-').
But I don't quite understand it. What is an extended regex?
GNU grep -E attempts to support traditional usage by assuming that { is not special if it would be the start of an invalid interval specification. For example, the command grep -E '{1' searches for the two-character string {1 instead of reporting a syntax error in the regular expression.
grep and egrep does the same function, but the way they interpret the pattern is the only difference. Grep stands for "Global Regular Expressions Print", were as Egrep for "Extended Global Regular Expressions Print".
Both egrep and fgrep are derived from the base grep command. The “egrep” stands for “extended grep” while the fgrep stands for “fixed-string grep.” 2.An egrep command is used to search for multiple patterns inside a file or other kind of data repository while frgrep is used to look for strings.
Egrep Command This version of grep is efficient and fast when it comes to searching for a regular expression pattern as it treats meta-characters as is and doesn't substitute them as strings like in grep, and hence you are freed from the burden of escaping them as in grep.
As you mentioned, grep -E
is for extended regular expressions whereas . From the man page:-e
is for basic regular expressions
EDIT: As Jonathan pointed out below, grep -e
"specifies that the following argument is (one of) the regular expression(s) to be matched."
Basic vs Extended Regular Expressions
In basic regular expressions the meta-characters
?
,+
,{
,|
,(
, and)
lose their special meaning; instead use the backslashed versions\?
,\+
,\{
,\|
,\(
, and\)
.Traditional
egrep
did not support the{
meta-character, and someegrep
implementations support\{
instead, so portable scripts should avoid{
ingrep -E
patterns and should use[{]
to match a literal{
.GNU
grep -E
attempts to support traditional usage by assuming that{
is not special if it would be the start of an invalid interval specification. For example, the commandgrep -E '{1'
searches for the two-character string{1
instead of reporting a syntax error in the regular expression. POSIX.2 allows this behavior as an extension, but portable scripts should avoid it.
But man pages are pretty terse, so for further info, check out this link:
http://www.regular-expressions.info/posix.html
The part of the manpage regarding the {
meta character though specifically talks about what you are seeing with respect to the difference.
grep -e "[0-9]{3}-[0-9]{3}-[0-9]{4}"
won't work because it is not treating the {
character as you expect. Whereas
grep -E "[0-9]{3}-[0-9]{3}-[0-9]{4}"
does because that is the extended grep version — or the egrep
version for example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With