sed command to add a new column entry

My input file looks like this

12	3	5.122.281.413	172.31.15.220	3421	4133	2	2	1454	3421	4133	2	2	0	
12	44036	214.215.52.146	90.123.245.211	2312	3911	4	4	521	2312	3911	4	4	1	
14	504	6.254.324.219	192.61.27.120	4444	5611	7	5	1415	4444	5611	7	5	1	
13	9	146.216.51.151	5.132.212.115	5432	6123	9	1	78	5432	6123	9	1	1	
16	41228	96.201.221.214	5.132.212.115	3411	5120	3	3	1358	3411	5120	3	3	1	

my aim is to convert these ip address to a decimal form using this formula
so if my ip address is 192.168.1.2
my result

192 x (256)^3 + 168 x (256)^2 + 1 x (256)^1 + 2 (256)^0 = ?
3221225472 + 11010048 + 256 + 2 = 3232235778

so for input file, my output file has to be

12	13	121.34.21.106	123.555.232.101	3212	4573	2	8	1497	4312	4573	2	8	1	2032276842	2100029541
12	59	102.212.234.12	96.201.221.215	3412	5557	9	7	1498	1212	5557	9	7	1	1725229580	1623842263
14	22	111.116.149.61	121.51.26.198	2122	4122	6	9	1498	344122	4122	6	9	0	1869911357	2033392326
13	10	214.328.274.31	122.81.25.110	2311	3632	4	7	1471	2311	3632	4	7	0	3611890207	2052135278
16	12	121.85.52.235	87.183.82.42	3311	3922	3	1	1495	3311	3922	3	1	1	2035627243	1471631914

Is there a sed or awk one liner that can do this:

I tried this:

sed 's/. 256^3\+\.256^2\+\.256\+\.\' input.txt> outfil.txt

Also if I do

sed 's/[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+/XXX.XXX.XXX.XXX/g' ./ input.txt>output.txt     

will this be a non integer value?

First, sed does not have the ability to perform arithmetic operations on strings. Second, your first sed command does not contain a valid substitute command. Third, your second sed command tries to edit a directory (i.e., ./ ) and sed only operates on text files; not directories. And, fourth, the regular expression that is your search pattern in your second sed command looks for a single digit followed by a plus-sign followed by a period followed by a single digit followed by a plus-sign followed by a period followed by a single digit followed by a plus-sign followed by a period followed by a single digit, but that pattern does not match any text in any line in your sample input.

The awk utility, however, is perfectly capable of simple arithmetic like this. However, you will not get unique integer values if any of the four numbers in an IP address is larger than 255 with the algorithm you're using to convert an IP address to an integer AND, I don't get the output values you say you expect for any of the in IP addresses you supplied??? If all four numbers in your IP addresses are in the range 0 through 255, using the algorithm you specified, the result will fit in an unsigned 32-bit integer. It will fit in a signed 32-bit integer if and only if the 1st number is in the range 0 through 127.

You might try the following awk script and see if it comes close to the results you want:

awk '
function IP2int(IP,	a, n) {
	n = split(IP, a, /[.]/)
	if(n != 4 || a[1] > 255 || a[2] > 255 || a[3] > 255 || a[4] > 255)
		return("invalid IP")
	return(a[1] * 256 ^ 3 + a[2] * 256 ^ 2 + a[3] * 256 + a[4])
}
BEGIN {	FS = OFS = "\t"
}
{	print $0, IP2int($3), IP2int($4)
}' input

with the sample input you showed us in post #1, the above code produces the output:

12	3	5.122.281.413	172.31.15.220	3421	4133	2	2	1454	3421	4133	2	2	0		invalid IP	2887716828
12	44036	214.215.52.146	90.123.245.211	2312	3911	4	4	521	2312	3911	4	4	1		3604427922	1518073299
14	504	6.254.324.219	192.61.27.120	4444	5611	7	5	1415	4444	5611	7	5	1		invalid IP	3225230200
13	9	146.216.51.151	5.132.212.115	5432	6123	9	1	78	5432	6123	9	1	1		2463642519	92591219
16	41228	96.201.221.214	5.132.212.115	3411	5120	3	3	1358	3411	5120	3	3	1	1623842262	92591219

Note that there is an empty field before the two added fields in all but the last line of input because your sample input file has an empty field (i.e., a tab character) at the end of each of those lines.

You didn't tell us what shell or operating system you're using. If you want to try this on a Solaris/SunOS system, change awk in the above script to /usr/xpg4/bin/awk or nawk .

1 Like

For the IP2int function, try also

function IP2int(IP)     {split (IP, T, ".")
                         TMP = sprintf ("0X%02X%02X%02X%02X", T[1], T[2], T[3], T[4])
                         printf (length(TMP) <= 10) ? "%.f\n" : "illegal IP: %s\n",  TMP
                        }
.
.
.
illegal IP: 0X057A11919D
3604427922
illegal IP: 0X06FE144DB
2463642519
1623842262
2 Likes