1

I am new to Bash scripting and I need help with something.

The file bbb.txt contains many IPv4 and IPv6 addresses, like this:

10.0.2.15    fe80...
192.168.1.1   fe80...

The file aaa.txt has many iptables commands.

I want my script to find all IPv4 addresses in aaa.txt and check if they can be found in bbb.txt, when matched - IPv4 in aaa.txt is replaced with IPv6 from bbb.txt. Is it doable?

0

2 Answers 2

1

I think you're better off using perl for this:

#!/usr/bin/perl

use strict;
use warnings;

my $file1 = 'aaa.txt';
my $file2 = 'bbb.txt';

open my $if1,'<',$file1 or die "$file1: $!\n";
open my $if2,'<',$file2 or die "$file2: $!\n";

my %ip_dictionary;
while(<$if2>){
    my ($ipv4,$ipv6)=split;
    $ip_dictionary{$ipv4}=$ipv6;
}
close $if2;

my $slurp = do { local $/; <$if1>};
close $if1;

$slurp=~ s!((?:[0-9]{1,3}\.){3}[0-9]{1,3})!exists $ip_dictionary{$1} and is_valid_ip($1) ? $ip_dictionary{$1} : $1!eg;

open my $of,'>',$file1;
print $of $slurp;

sub is_valid_ip{
    my $ip=shift//return 0;
    for(split /\./,$ip){
        return 0 if $_ > 255;
    }
    1
}
Sign up to request clarification or add additional context in comments.

Comments

0

Save this to a file e.g. script.sh.

#!/bin/bash
declare -A A
while read -ra __; do
    A[${__[0]}]=${__[1]}
done < "$2"
while read -r __; do
    for I in "${!A[@]}"; do
        [[ $__ == *"$I"* ]] && {
            V=${A[$I}
            __=${__//"$I"/"$V"}
        }
    done
    echo "$__"
done < "$1"

Then run bash script.sh aaa.txt bbb.txt.

To get the output run it as something like bash script.sh aaa.txt bbb.txt > out.txt

I prefer to use Bash this time since you have to quote non-literals in Awk.

Another solution through Ruby:

ruby -e 'f = File.open(ARGV[0]).read; File.open(ARGV[1]).readlines.map{|l| l.split}.each{|a| f.gsub!(a[0], a[1])}; puts f' aaa.txt bbb.txt

Another way to modify file directly:

#!/bin/bash
A=$(<"$1")
while read -ra B; do
    A=${A//"${B[0]}"/"${B[1]}"}
done < "$2"
echo "$A" > "$1"

Run as bash script.sh aaa.txt bbb.txt.

Another through Ruby:

ruby -e 'x = File.read(ARGV[0]); File.open(ARGV[1]).readlines.map{|l| l.split}.each{|a| x.gsub!(a[0], a[1])}; File.write(ARGV[0], x)' aaa.txt bbb.txt

1 Comment

Nice replies, thanks. Can you tell me why the file aaa.txt is not changed? In other words: effects are not saved, I want script.sh to change aaa.txt after finding a match in bbb.txt.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.