Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

please advice how to match only the valid IPs ( ) from the file.txt and insert only the valid IP into VALID_IP.txt file

  • ( see VALID_IP.txt for example )

the solution should be implemented in my ksh script ( so perl or sed or awk is fine also )

more file.txt


example of VALID_IP.txt file
share|improve this question
up vote 4 down vote accepted

The following is a suitable regex, split onto 4 different lines for the sake of my own sanity.



egrep -o `cat regex` infile #all regex lines above joined, no spaces

Obviously this doesn't match your example. Why? Because we can't tell that that a 3 doesn't belong with a one. As you can see, garbage numbers can't be cleanly guessed at.

share|improve this answer
but how to add this to my ksh script ? – yael Nov 15 '12 at 8:51
@yael use egrep -o – Jeff Ferland Nov 15 '12 at 9:03
If you use grep -oP you can use look-around constraints to limit the invalid first and last octets: grep -oP '(?<!\d)(1?\d?\d|2[0-4]\d|25[0-5])(\.(1?\d?\d|2[0-4]\d|25[0-5])){3}(?!\d)' – glenn jackman Nov 15 '12 at 12:28
@glennjackman Good point. It didn't click to me that none of the "extra digits" numbers were included in the example output, probably from a combination of it being very late at night my time and the syntax highlighting. Definitely should use negations in this circumstance, yet be aware that one extra digit of nonsense could still make a valid IP depending on the digit. – Jeff Ferland Nov 15 '12 at 22:56
@Jeff your solution is fine for linux but the egrep flag for solaris is diffrent , can you please advice what the same solution for solaris machines ? – yael Nov 18 '12 at 6:48

It's slightly cleaner with perl

use Regexp::Common qw/net/;
while (<>) {
      print $1, "\n" if /($RE{net}{IPv4})/;

but it still gets false positives

Perl one liner

perl -e 'use Regexp::Common qw/net/;while (<>) {print $1, "\n" if /($RE{net}{IPv4})/;}' infile
share|improve this answer
is it possible to translate this perl script to one perl line so I will add this to my ksh script ? – yael Nov 15 '12 at 9:50
@yael: see my edit – Iain Nov 15 '12 at 10:39
Use lookaround assertions to eliminate the false positives: /(?<!\d)($RE{net}{IPv4})(?!\d)/ – glenn jackman Nov 15 '12 at 12:30
In fact, can tighten up the one-liner: perl -MRegexp::Common=net -lne 'print for /(?<!\d)($RE{net}{IPv4})(?!\d)/' – glenn jackman Nov 15 '12 at 14:20

I recommend using range checking instead of hairy regexes. You can do this in ksh without using an external utility or another language. Although Iain's solution is nice, it's not a core module.

Here's pure ksh. There's no need to make it a one-liner, just use a function. Code like this is easier to understand, easier to check for correctness and easier to maintain.

validate_ip () {
    typeset ip=$@
    typeset IFS=. valid=1
    typeset octets=($ip) octet
    typeset digits='^[[:digit:]]+$'

    if (( ${#octets[@]} == 4 ))
        for ((octet = 0; octet <= 3; octet++))
            if [[ ! "$value" =~ $digits ]] || ((value < 0 || value > 255))

    if ((valid))
        printf '%s\n' "$ip"

    return $valid

while read -r line
    validate_ip "$line"
done #< file.txt > VALID_IP.txt

This is ksh 93, I haven't tested it in ksh 88. It also runs unchanged in Bash 3.2 or higher.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.