Alternate for sed -i in AIX

Experts,

At the moment I am working in AIX box where sed -i is not available.
My requirement is as below

Two files file1 and file2. file1 contains the IP address, its count. file2 contains the Hostname and its corresponding IP address. I would like get the IP address replaced with the apt Hostname in file1.

# cat file1
192.168.20.8    => 1
192.168.20.24   => 2
192.168.20.6    => 2
192.168.20.7    => 3
192.168.20.9    => 3
192.168.20.25   => 4
192.168.20.26   => 4
192.168.20.23   => 6
# cat file2
192.168.20.6    ser70
192.168.20.7    ser71
192.168.20.8    ser72
192.168.20.9    ser73
192.168.20.23   ser80
192.168.20.24   ser81
192.168.20.25   ser82
192.168.20.26   ser83

My code is of:

for i in `awk '{print $1}' file1`
	do
	svr=$(grep $i file2 | awk '{print $2}')
	sed -i "s/$i/$svr/" file1
done

Expected Output:

# cat file1
ser72    => 1
ser81   => 2
ser70    => 2
ser71    => 3
ser73    => 3
ser82   => 4
ser83   => 4
ser80   => 6

But unfortunately sed -i is not present in my AIX box, please shoot me an alternative. :slight_smile:
Also if the IP address is not found in file2, that row should be left untouched in file1.

Doubtless you can simplify the code further, i.e. by using awk to read both files and substitute the correct values. You would then write this to a temporary file and copy that over the original.

Otherwise, using ed is an easy way to begin with:

ed file1 << !
, s/$i/$svr/
w
q
!
1 Like

You could use use awk:

awk 'NR == FNR {
  iton[$1] = $2
  next
  }
($1 in iton && $1 = iton[$1]) || 1
  ' file2 file1 > _tmp_file_ &&
      mv -- _tmp_file_ file1

If the original order is not important and your shell supports process substitution (zsh, ksh93 and bash):

join <(sort file2) <(sort file1) -o1.2,2.2,2.3
1 Like

Thanks for the prompt response Scott
Is the below right ?

for i in `awk '{print $1}' file1`
	do
	svr=$(grep $i file2 | awk '{print $2}')
	ed file1 << EOD
		, s/$i/$svr/
		w
		q
	EOD
done

Only if the closing EOF is indented with a TAB (or nothing at all - it won't work if those are spaces before it).

A note to radoulov's solution (which is nice :)). Moving a temporary file over an existing file can be dangerous.

I did that once, and it caused no end of grief!

# ls -l rc.tcpip
-rwxrwxr-- 1 root system 6409 Aug 21 2009 rc.tcpip
 
# sed "s/change_this/to_this/" rc.tcpip > _tmp_rc_tcpip
# mv _tmp_rc_tcpip rc.tcpip
# ls -l rc.tcpip
-rw-r--r-- 1 root system 6406 Jan 7 2013 rc.tcpip

rc.tcpip won't get executed after a reboot. You can guess what happened next :slight_smile:

2 Likes

WOW!!

This works out, can you please explain the code.

Great point Scott!
sed's -i is far more sophisticated (if I recall correctly, it handles even extended acls).

To the OP: with this manual method you'll need to handle the file permissions/inode changes manually ...

awk 'NR == FNR {
  # while reading the fist input file
  # store the names in an array
  # keyed by the IPs
  iton[$1] = $2
  next
  }
# if the IP has an associated name
# assign its value to $1
# otherwise just return the record
# 1 -> true -> print $0  
($1 in iton && $1 = iton[$1]) || 1
  ' file2 file1 > _tmp_file_ && 
      mv -- _tmp_file_ file1      
1 Like