Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

IP Address Unix Script Help 1

Status
Not open for further replies.

bishop15

Technical User
May 6, 2003
4
US
This sure seems simple enough, but I seem to be stuck. Each morning, via another script I get emailed a mass listing of nothing but IP address. I would like a script that takes this list, sorts the IP's according to classes, and outputs all non "c" class ip's into a new file....the sorting part is easy but I'm stuck on how to output the non "c" class IP's into another file. Any help would be greatly appreciated.
 
Code:
{
    array[NR]=$0
}
END        {
       for (i=1 ; i <= (NR - 1)  ; i++) {
            for (p=(i + 1) ; p <= NR ; p++) {
                 split(array[i],arr1,&quot;.&quot;)
                 split(array[p],arr2,&quot;.&quot;)
                 if (arr1[1] < arr2[1] && arr1[1] <= 192) {
                    tmp = array[i]
                    array[i] = array[p]
                    array[p] = tmp
              }  else if (arr1[1] >= 192) {
                    delete array[i]
              }
          }
      }
     
       for (x=1 ; x <= NR ; x++) {
            print array[x] >> filename
        }
}

It's a quick hack, and I'm sure there are cleaner ways.
Whatever, it works here with a file that looks like this:
124.34.2.123
43.12.56.78
143.6.78.90
212.3.45.67
112.45.6.78.9
177.45.32.6
190.45.6.78
193.234.15.67
222.1.34.177

Output:
190.45.6.78
177.45.32.6
143.6.78.90
124.34.2.123
112.45.6.78.9
43.12.56.78

 
Thanks for the post Marsd....is it possible to sort or group all given IP's into classes if it applies?

ex.
111.22.33.[1-5] &quot;C-class&quot; IP Address
111.22.* &quot;B-class&quot; IP Address

 
Ahh..
So you are using classless conventions but with
truncated addresses to denote the class(?), or are
you using vlsm notation of some kind or subnet mask
along with address?

If you don't have any of this information, I don't see
how you can figure out which is which aside from the
'traditional' classful boundaries.
Could you post a before and after result you would
like from a data sample?

 
My apologies, I can certainly see the confusion. Again, I'd really appreciate any help you can provide. I have a script which spits out convetional IP ranges.
ex. (made up IP's)
123.45.67.8
32.5.26.32

The current script that is setup does not make use of subnet. Immediately below is an example of what my script currently in place, will generate.
ex. (made up IP's)
123.2.14.25
62.85.6.3
32.62.85.10
123.2.14.26
123.2.14.20
62.85.6.5
32.76.3.3
13.2.25.63

First, I'd like to sort these random IP's into order.
ex. from above list
13.2.25.63
32.62.85.10
32.76.3.3
62.85.6.3
62.85.6.5
123.2.14.20
123.2.14.25
123.2.14.26

Next, (and this is where it gets complicated if at all possible) I'd like for the script to check each of the first three occulate IP ranges, (123.2.14) if the first three ranges are the same, &quot;class c&quot; keep them in the file, if not export all remaining IP's, that don't meet the above requirements, to another file.
ex. *These IP ranges would stay in the file
62.85.6.3
62.85.6.5
123.2.14.20
123.2.14.25
123.2.14.26

*While these remaining IP's would be sent to a new file
13.2.25.63
32.62.85.10
32.76.3.3
 
Code:
function firstthree(val, xv) {
         sub(/\.[0-9]+$/,&quot;&quot;,val)
         return val
}

function allmatches(aname,aval,p1) {
              for (all in aname) {
                  ptr = firstthree(aname[all])
                  #printf(&quot;Comparing %s to %s\n&quot;, ptr, aval)
                  if (aval == ptr && all != p1) {
                      #printf(&quot;Found match at %s vs %s, count = %d\n&quot;,aval,ptr,all)
                      return 1;
                  }
               }
return 0
}
        


{
    array[NR]=$0
}
END        {
       for (i=1 ; i <= (NR - 1)  ; i++) {
            for (p=(i + 1) ; p <= NR ; p++) {
                 split(array[i],arr1,&quot;.&quot;)
                 split(array[p],arr2,&quot;.&quot;)
                 if (arr1[1] > arr2[1] && arr1[1] < 192) {
                    tmp = array[i]
                    array[i] = array[p]
                    array[p] = tmp
              }  else if (arr1[1] >= 192) {
                    delete array[i]
              }
          }
      }

       a=0 
       print &quot;No keepers&quot;
       for (x=1 ; x <= NR ; x++) {
            if (array[x]) {
               new = firstthree(array[x])
               if ((allmatches(array,new,x)) < 1) {
                    print array[x]
               }  
            } 
       }              
}

File like this:
124.34.2.123
43.12.56.78
143.6.78.90
212.3.45.67
112.45.6.78
177.45.32.6
190.45.6.78
193.234.15.67
222.1.34.177
124.34.2.45
124.34.2.12
143.6.78.70

Output:
time awk -f ss1.awk class.txt
No keepers
43.12.56.78
112.45.6.78
177.45.32.6
190.45.6.78

real 0m0.011s
user 0m0.010s
sys 0m0.000s
 
Final hack job: I'm just brute forcing this whole thing
btw. If you find a cleaner method post it for posterity.


Code:
function firstthree(val, xv) {
         sub(/\.[0-9]+$/,&quot;&quot;,val)
         return val
}


function splitnprint(lis, z,pp) {
z = split(lis,arr1)

         while (pp <= z) {
               print arr1[pp]
               pp++
         }
}             
     

function allmatches(aname,aval,p1) {
              for (all in aname) {
                  ptr = firstthree(aname[all])
                  #printf(&quot;Comparing %s to %s\n&quot;, ptr, aval)
                  if (aval == ptr && all != p1) {
                      #printf(&quot;Found match at %s vs %s, count = %d\n&quot;,aval,ptr,all)
                      return 1;
                  }
               }
return 0
}
        
function genlist(aname,aval,ccnt,max,list,f, y,pt) {
              
             for (y=ccnt ; y <= max ; y++) {
                  pt = firstthree(aname[y])
                  if (aval == pt && y != ccnt) {
                     f += 1
                     list = list&quot; &quot;aname[y]
                     aname[y] = 0
                     ccnt = y 
                     return genlist(aname,aval,ccnt,max,list,f)
                  }                     
            }
  if (f > 1) {
    return list
  }
}

{
    array[NR]=$0
}
END        {
       for (i=1 ; i <= (NR - 1)  ; i++) {
            for (p=(i + 1) ; p <= NR ; p++) {
                 split(array[i],arr1,&quot;.&quot;)
                 split(array[p],arr2,&quot;.&quot;)
                 if (arr1[1] > arr2[1] && arr1[1] < 192) {
                    tmp = array[i]
                    array[i] = array[p]
                    array[p] = tmp
              }  else if (arr1[1] >= 192) {
                    delete array[i]
              }
          }
      }

       a=0 
       print &quot;No keepers&quot;
       for (x=1 ; x <= NR ; x++) {
            if (array[x]) {
               new = firstthree(array[x])
               if ((allmatches(array,new,x)) < 1) {
                    print array[x]
               }  
               sortarr[a++] = genlist(array,new,1,NR,&quot;&quot;,0)
            } 
       } 
          printf(&quot;\nKeepers:&quot;)
          for (mm=1 ; mm <= a ; mm++) {
              if (sortarr[mm]) {
                  splitnprint(sortarr[mm])
              }
          }         
}

Final:
time awk -f ss1.awk class.txt
No keepers
43.12.56.78
112.45.6.78
143.12.3.45
177.45.32.6
190.45.6.78

Keepers:
124.34.2.45
124.34.2.12
124.34.2.67
124.34.2.123

143.6.78.9
143.6.78.90
143.6.78.70

real 0m0.017s
user 0m0.010s
sys 0m0.000s
 
Marsd,
Sorry about the late response. I pulled one of my dev's and we came up with this....


$infile='iptest';
$mipfile='multipleips.txt';
$sipfile='singleips.txt';

sub main {

open IN,$infile; # Open the datafile

while ($line=<IN>) {
chomp $line; # Get rid of that pesky newline character
if ($line) { # make sure it isnt a blank line
$line=~/^(\d+\.\d+\.\d+)\.\d+/;
$subnet=$1;
$ipsub{$subnet}=$ipsub{$subnet}+1;
#print &quot;$line\t$subnet\n&quot;; #a test print to make sure things are working, Delete this line
push (@ipadd,$line); #push the ips into an array
}
}
close IN;
open MOUT,&quot;>>$mipfile&quot;; #open outfiles
open SOUT,&quot;>>$sipfile&quot;;
foreach $ip (@ipadd) {
$ip=~/^(\d+\.\d+\.\d+)\.\d+/;
$sub1=$1;
if ($ipsub{$sub1}>1) {
print MOUT &quot;$ip\n&quot;;
}
elsif ($ipsub{$sub1}==1) {
print SOUT &quot;$ip\n&quot;;
}

}
}
main();

Thanks so much again for your help!!
 
No problem..glad you got something to work for you.
I don't grok perl too well, but it looks like you
never needed a sort. Just a simple exclusion search
with a single condition.

FYI: Awk can do that as easily as perl in it's main
loop.

For fun run the awk script through a2p and see
how it looks in perl.
It's slower(!).
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top