You used a POSIX ERE pattern, but did not pass -E
option to have grep
use the POSIX ERE flavor. Thus, grep
used POSIX BRE instead, where you need to escape {n,m}
quantifier and (...)
to make them be parsed as special regex operators.
Note you need to escape a .
so that it could only match a literal dot.
To make your pattern work with grep
the way you wanted you could use:
grep -E '([0-9]{1,3}.?){4}' # POSIX ERE
grep '([0-9]{1,3}.?){4}' # POSIX BRE version of the same regex
See an online demo.
However, this regex will also match a string of several digits because the .
is optional.
You may solve it by unrolling the pattern as
grep -E '[0-9]{1,3}(.[0-9]{1,3}){3}' # POSIX ERE
grep '[0-9]{1,3}(.[0-9]{1,3}){3}' # POSIX BRE
See another demo.
Basically, it matches:
[0-9]{1,3}
- 1 to 3 occurrences of any ASCII digit
(.[0-9]{1,3}){3}
- 3 occurrences of:
.
- a literal .
[0-9]{1,3}
- 1 to 3 occurrences of any ASCII digit
To make sure you only match valid IPs, you might want to use a more precise IP matching regex:
grep -E '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}' # POSIX ERE
See this online demo.
You may further tweak it with word boundaries (can be <
/ >
or
), etc.
To extract the IPs use -o
option with grep
: grep -oE 'ERE_pattern' file
/ grep -o 'BRE_pattern' file
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…