I am trying to figure out how to use the grep regex command to filter out IPs.
My first problem is to tell how many IPs only have one digit in the first octet.
And the second is to find all IPs with the number 244 in the first octet.
Ive tried grep -o -n '\b[0-9].' file.txt
but this just finds any 1 digit, then I also tried setting up each place [0-9]{1,3} but I still dont get the righ output.
In an RE (regular expression) the dot means "any character"; you certainly want \. or [.] which means a literal dot.
Even this is not precise enough; the \b boundary can match a preceding dot, so it is a single-digit somewhere (but at the very end - a dot must follow).
With this input file you can use the ^ to mark the beginning of the line.
Then, the -o option returns only the matched portion, not the full line. With the -o you must cover the entire IP address.
Yes:
the {1,3} quantifier works in ERE.
But grep defaults to BRE where it is \{1,3\}
You can switch to ERE with grep -E ... or egrep ...
Another potential problem is \b (word boundary) that works in certain GNU/Linux versions only. Safer is \< (left word boundary, and \> is right word boundary).
However, most precise is ^ (the beginning of the line, and $ marks the end of the line).
How many IPs only have one digit in the first octet
First, you need the atom for beginning of line^, which in a regex represents a null stringand is a meta character. In addition, the character class for digits [:digit:]or a range0-9 (the minus - works as a shorthand for 012..9), enclosed by brackets [], which represent a non-empty list of charachters. Inside brackets, any meta character looses its meta property.
Without further quantifiers, both bracket expressions [[:digit:]] and [0-9] match exactly one digit. But since we have to 'count' the digits of the first octet, we need in addition the octet separator, namely the dot .. But in a regex, it's another meta character, it stands for resp. represents any single character. To override its meta property, it must either be escaped by a \ or be enclosed by brackets (see above):
$ grep '^[0-9]\.' file.txt
# or
$ grep ^[0-9]\\. file.txt # w/o quotes, so double escaped due to shell's interpretation
# or
$ grep ^[[:digit:]][.] file.txt
# or
$ grep ^[0-9][.] file.txt