Home > Enterprise >  Bash script find sequence numbers of ip address
Bash script find sequence numbers of ip address

Time:04-06

i want to find a sequence numbers in a file(bash script),if anyone can give me a tip. I have a file with ip address

like. 172.15.0.1 172.15.0.6 172.15.0.7 172.15.0.8 172.15.0.10 172.15.0.15 172.15.0.16

And i want to find lets say the 3 first sequence numbers

like this 172.15.0.6 172.15.0.7 172.15.0.8

i tried with grep or sed or awk or loops but i couldn't find the results i want.

CodePudding user response:

Would you please try the bash script:

#!/bin/bash

report() {
    local seg=${1%.*}
    for (( i = $2 - 2; i <= $2; i   )); do
        echo "$seg.$i"
    done
}

prev=255                                # initial value as a workaround
while IFS= read -r ip; do
    n=${ip##*.}                         # extract the last octet
    if (( n == prev   1 )); then
        (( count   ))
        if (( count >= 2 )); then       # found three sequences
            report "$ip" "$n"           # then report them
        fi
    else
        count=0                         # reset the count if fail
    fi
    prev=$n
done < <(tr -s ' ' '\n' < input_file.txt | sort -t. -nk4,4)

where input_file.txt is the filename which contain the ip addresses.
Output with the provided file:

172.15.0.6
172.15.0.7
172.15.0.8
  • tr -s ' ' '\n' replaces the whitespaces with newline characters so the output can be fed to sort command.
  • sort -t. -nk4,4 sorts the input with the last octet in numerical order.
  • The output is fed to the while loop via the process substitution < <(commands).
  • Now the while loop process the input line by line (ip by ip).
  • The variable n is assigned to the last (4th) octet.
  • n is compared with the prev which holds the number in the last line. If n == prev 1 holds, the numbers are in sequence. Then count is accumulated.
  • If count reaches 2, the three lines including the current line are in the sequence. Then parameters are passed to the function report.

CodePudding user response:

Given a file with a range of ip addresses separated by whitespace this awk solution might be what you're looking for:

$ awk -vRS=" " '/172.15.0.[6-8]/{print}' file.txt 
172.15.0.6
172.15.0.7
172.15.0.8

The -vRS part means that the RS (record separator) variable is set to one whitespace character.

CodePudding user response:

This should give:

echo "172.15.0.1 172.15.0.6 172.15.0.7 172.15.0.8 172.15.0.10 172.15.0.15 172.15.0.16" | grep -oP $(echo 172.15.0.{6..8} | tr ' ' '|')
172.15.0.6
172.15.0.7
172.15.0.8

EDIT2:

Here's my second attempt:

j=0
i=2
myip=172.15.0
allIPs="$myip.1 $myip.2 $myip.6 $myip.7 $myip.8 $myip.10 $myip.15 $myip.16"
# while less or equal than 255
while [ $i -le 255 ] ; do
    # we will build a string that has a sequence range, for example 172.15.0.38|172.15.0.39|172.15.0.40
    ips=""
    # this builds the ip range sequence and adds it to ips
    for ip in $(seq $j $i); do ips=${ips}$(echo -n 172.15.0."$ip")"|"; done
    # we remove the last character which is '|'
    ips=${ips::-1}
    # this is the result that will match the sequence range
    res=$(echo $allIPs | grep -oP $ips)
    # if it matches, it will print it by checking that the IPs are actually found
    if [ $(echo $res | tr ' ' '\n' | wc -l) == 3 ]; then 
        echo $res
    fi
    # to next range
    j=$i
    i=$(( $i   2 ))
done
# this is for the last sequence which is 253, 254, 255
res=$(echo $allIPs | grep -oP "$myip.253|$myip.254|$myip.255")
if [ $(echo $res | tr ' ' '\n' | wc -l) == 3 ]; then echo $res; fi

should give

172.15.0.6 172.15.0.7 172.15.0.8
  • Related