0

I have

#!/bin/sh
tcpdump -c 1 -eni any host 100.80.1.252 > tcpd.txt
sleep 2
awk 'NR==1{print $9}' tcpd.txt > ip.txt
sleep 2
cat ip.txt

output is 100.70.62.33

Now I want to change every 100.70.x.x address from file1 with one stored in ip.txt file

What i want to achieve:

I have a sh script that is calling some iptables rules (this is the file where i want to modify 100.70.x.x IP)

cat set_direct_routing_server_2.sh

#!/bin/sh
iptables -t nat -F

iptables -t nat -A PREROUTING --source 192.168.219.2 --destination 192.168.219.4/30 -j DNAT --to-destination 100.70.62.21
iptables -t nat -A PREROUTING --source 100.70.62.21 --destination 100.80.1.252 -j DNAT --to-destination 192.168.219.2
iptables -t nat -A POSTROUTING --source 100.70.62.21 -j SNAT --to-source 192.168.219.6

ipstables -t nat -L

master.sh is the script i was talking in first post:

#!/bin/sh
tcpdump -c 1 -eni any host 100.80.1.252 > tcpd.txt
sleep 2
awk 'NR==1{print $9}' tcpd.txt > ip.txt
sleep 2
cat ip.txt
sleep 2
sed -i "s/100\.70\.[0-9]\{1,3\}\.[0-9]\{1,3\}/$(<ip.txt)/g" set_direct_routing_server_2.sh
cat set_direct_routing_server_2.sh

When I call master.sh I have following output.

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes 1 packet captured 2 packets received by filter 0 packets dropped by kernel 100.70.62.33 #!/bin/sh iptables -t nat -F

iptables -t nat -A PREROUTING --source 192.168.219.2 --destination 192.168.219.4/30 -j DNAT --to-destination
iptables -t nat -A PREROUTING --source  --destination 100.80.1.252 -j DNAT --to-destination 192.168.219.2
iptables -t nat -A POSTROUTING --source  -j SNAT --to-source 192.168.219.6

ipstables -t nat -L

As you see 100.70.x.x address are only deleted

0
s=$(cat ip.txt)
awk -v s="$s"  '{gsub(/100.70.[0-9].{1,3}.[0-9]/, s)}1' file.txt

s=$(cat ip.txt) in this variable I store the output of a sub-shell

-v s="$s" here -v receives a shell variable both local and global. in this case and local.

 gsub stands for global substitution. It replaces every occurrence

/100.70.[0-9].{1,3}.[0-9]/ aki the regular expression to match all ip 100.70. *

, s this variable has the value of our sub-shell that was created at the beginning and takes it by the -v flag of awk, which at that moment will print its value.

1 Is seen as true and therefore is equivalent to print.

0

If you don't mind being a little loose on the IP address regular expression, you could use sed:

sed "s/100\.70\.[0-9]\{1,3\}\.[0-9]\{1,3\}/$(<ip.txt)/g" < file1 > output

or, with a sed that supports -i:

sed -i "s/100\.70\.[0-9]\{1,3\}\.[0-9]\{1,3\}/$(<ip.txt)/g" file1

The regular expression to match "100.70.x.x" addresses will match valid IP addresses as well as invalid ones, such as: 100.70.900.678, as the [0-9]\{1,3\} simply says to match between one and three digits.

The replacement text is done within the double-quotes via a special command substitution ($(< filename)) that simply reads the contents of the ip.txt file.

The g flag tells sed to replace every matching instance on each line. If you'll only have one IP address per line, there's no need for the g flag.

  • Hi Jeff, sed command is doing the job when is called manually but, added in a .sh script it only deletes 100.70.x.x entries and do not replace them. – Boris Oct 24 '18 at 7:45
  • The sed command expects the ip.txt file to be in your current directory..? – Jeff Schaller Oct 24 '18 at 9:41
  • yes, all files and script are in same directory – Boris Oct 24 '18 at 9:44
  • How are you calling the script? – Jeff Schaller Oct 24 '18 at 10:00

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.