jean
jean

Reputation: 251

using awk to replace a string by another string (mapping table contained in a file)

I would like to know if it's possible to do the following thing only using awk: I am searching some regex in a file Fand I want to replace the string (S1) that matches the regex by another string (S2). Of course, it's easy to do that with awk. But ... my problem is that the value of S2 has to be obtained from another file that maps S1 to S2.

Example :

file F:

abcd 168.0.0.1 qsqsjsdfjsjdf
sdfsdffsd
168.0.0.2 sqqsfjqsfsdf

my associative table in another file

168.0.0.1 foo
168.0.0.2 bar

I want to get:

this result:

abcd foo qsqsjsdfjsjdf
sdfsdffsd
bar sqqsfjqsfsdf

Thanks for help !

edit: if my input file is a bit different, like this (no space before IP address):

file F:

abcd168.0.0.1 qsqsjsdfjsjdf
sdfsdffsd
168.0.0.2 sqqsfjqsfsdf

i can't use $1, $2 variables and search in the associative array. I tried something like that (based on birei proposition) but it did not work :

FNR < NR {
    sub(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/, assoc [ & ] );
    print
}

Is there a way to search the matched string in the associative array (assoc[ & ] seems to be not valid) ?

Upvotes: 2

Views: 4724

Answers (1)

Birei
Birei

Reputation: 36262

One way. It's self-explanatory. Save data from the associative table in an array and in second file check for each field if it matches any key of the array:

awk '
    FNR == NR {
        assoc[ $1 ] = $2;
        next;
    }
    FNR < NR {
        for ( i = 1; i <= NF; i++ ) {
            if ( $i in assoc ) {
                $i = assoc[ $i ]
            }
        }
        print
    }
' associative_file F

Output:

bcd foo qsqsjsdfjsjdf                                                                                                                                                                                                                        
sdfsdffsd                                                                                                                                                                                                                                    
bar sqqsfjqsfsdf

EDIT: Try following awk script for IPs without spaces with their surrounding words. It's similar to previous one, but now it searches in the array and try to find an IP in any place of the line (default $0 for gsub) and substitutes it.

awk '
    FNR == NR {
        assoc[ $1 ] = $2;
        next;
    }
    FNR < NR {
        for ( key in assoc ) {
            gsub( key, assoc[ key ] )
        }
        print
    }
' associative_file F

Assuming infile with the conten of your second example of file F, output would be:

abcdfoo qsqsjsdfjsjdf                                                                                                                                                                                                                        
sdfsdffsd                                                                                                                                                                                                                                    
bar sqqsfjqsfsdf

Upvotes: 5

Related Questions