1

I'm having a list of strings (sorted IP address ranges) like this:

10.100.0.0-10.100.255.255 External: 2.2.2.2
10.120.0.0-10.255.255.255 External: 2.2.2.2
10.0.0.0-10.255.255.255 External: 3.3.3.3
192.168.160.1-192.168.160.255 External: 3.3.3.3
and so on..

How can I group these by the last string of each line so that the result would look similar to this:

External: 2.2.2.2
  10.100.0.0-10.100.255.255
  10.120.0.0-10.255.255.255

External: 3.3.3.3
  10.0.0.0-10.255.255.255
  192.168.160.1-192.168.160.255

Note: Handling of IP addresses is not required. We can treat these as strings as they are already sorted and ordered. I'm looking for a pure Bash solution (not Python) and preferably without xargs.

Thanks in advance!

  • Are the groups compact, i.e. are all of their members grouped together? – choroba Jul 4 at 21:14
  • Pure bash, or are grep/awk/sed fair game? – Jim L. Jul 4 at 21:17
  • grep/awk/sed are fully ok. all members are grouped together. – readline Jul 4 at 21:20
2

Remember the last external ip in a variable. If the new ip is different, print the new one. Then print the ip range.

#! /bin/bash
last_ip=""
while read range _e ip ; do
    if [[ $ip != "$last_ip" ]] ; then
        printf '\nExternal: %s\n' "$ip"
    fi
    printf '  %s\n' "$range"
    last_ip=$ip
done < "$1"
  • +1 Precisely what I had in mind. Only edit I would suggest is \n in front of External: as it appears the OP desires a blank line between groups. – Jim L. Jul 4 at 21:29
  • 1
    @JimL. Thanks, updated. It's also possible to remove the newline from the very first line, but let's keep some work for the OP. – choroba Jul 4 at 21:32
  • Thanks guys. I'll try to bring that in line with my one-liner after all the sorts and greps already being in place. – readline Jul 4 at 21:35
0
awk '{

if($2$3 in STORE){

##make column 2 and column 3 as key to store address.
STORE[$2$3]=STORE[$2$3]"\n""\t"$1  ##add new line here 

}
else{
##if key not in STORE, add first column with a tab 
STORE[$2$3]="\t"$1 

}
}
##print everything using END 

END{
for(add in STORE){
print add"\n"STORE[add]
}
}' file.txt

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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