5

I know this is possible, probably by using awk, but I can't think the solution for now.

How do I convert IP format from

10.1.1.1-10.1.1.3
10.100.100.11-10.100.100.31

to

10.1.1.1-3
10.100.100.11-31

Here is my attempt with cut, but didn't really work as expected.

wolf@linux:~$ echo 10.1.1.1-10.1.1.3 | cut -d . -f 1,2,3,4
10.1.1.1-10
wolf@linux:~$ 

wolf@linux:~$ echo 10.100.100.11-10.100.100.31 | cut -d . -f 1,2,3,4
10.100.100.11-10
wolf@linux:~$ 
1

5 Answers 5

6

Here’s a generic solution using AWK, adapting to the number of common components:

BEGIN {
    FS = "-"
}

NF == 2 {
    split($1, start, /\./)
    split($2, end, /\./)
    printf $1
    for (i = 1; i <= length(start); i++) {
        if (start[i] != end[i]) {
            for (j = i; j <= length(end); j++)
                printf "%s%s", (j > i ? "." : "-"), end[j]
            print ""
            next
        }
    }
    print ""
}

This will also handle cases like 1.2.3.4-1.2.5.6, printing the correct range:

1.2.3.4-5.6
0
4

Here's a sed approach. It will look for everything up to the last - on the line, save that as \1, then save the last occurrence of a . followed by one or more digits as \2. The entire line is then replaced by \1\2:

$ sed -E 's/(.*-).*\.([0-9]+)/\1\2/' file 
10.1.1.1-3
10.100.100.11-31

Alternatively, in awk, you could set the input field separator to . or -, and the output field separator to ., and then print the frist through fourth fields, a - and the last field:

$ awk -F'[-.]' -vOFS="." '{print $1,$2,$3,$4"-"$NF}' file 
10.1.1.1-3
10.100.100.11-31
4

An option with awk:

awk -F'[.-]' '{ print $1"."$2"."$3"."$4"-"$8 }'

Output:

10.1.1.1-3
10.100.100.11-31
1
LC_ALL=C sed 's/^\([0-9.]*\.\)\([0-9]\{1,\}-\)\1\([0-9]\{1,\}\)$/\1\2\3/'

Would give the expected output for lines that are in the anything.digits-anything.digits and leave the lines that don't match that pattern (like 1.2.3.4-1.2.6.254) alone.

1
$ sed 's/-.*\./-/' file
10.1.1.1-3
10.100.100.11-31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .