Reputation: 35
I am using the below script to try to search and replace multiline pattern using awk . The awk script when used directly works fine but while trying the implement the functionality through a bash script by passing command line arguments , the arguments do not get placed into awk as expected and produce undesirable results . A sample file I used to test the awk script and expected result is as below :
File :
<A>
<B>
Port id=X
<C>
Port id=hey
Port no=hi
</C>
</B>
Port id=Z
</A>
Now if I want to replace the 'Port' by Network' , but only under the scope .. , I would simply run the awk as below and that does the trick :
awk '/<A>/,/<C>/ {gsub(/Port/,"Network"); } {print;}' filename
Output :
<A>
<B>
Network id=X
<C>
Port id=hey
Port no=hi
</C>
</B>
Port id=Z
</A>
I am trying to make the functionality generic by writing a script as below which takes the filename , scope , pattern to be replaced and pattern to be put in place as command line parameters and use them in awk script , however it doesn't work .
Could any one please help with how to pass the command line parameters to awk script to achieve the functionality that I could implement by executing the awk script directly ?
#!/bin/bash
echo "Enter file-name ,scope to be matched separated with space , pattern to be replaced , pattern to be placed"
echo "The file name is :$1 ,the scope to be matched : $2 - $3 , the pattern to be replaced is :$4 , pattern to be placed is: $5"
echo "Scope Start : $2"
echo "Scope End : $3"
awk -v F=$1 -v SS=$2 -v SE=$3 -v RE=$5 -v TRE=$4 '/"$SS"/,/"$SE"/ {gsub(/'"$TRE"'/,RE); } {print;}' "$1"
Upvotes: 1
Views: 351
Reputation: 44063
Several things:
$
is not used to expand a variable (unlike shell). Just use the variable name. $
makes it refer to a field -- for example, foo = 1; print $foo
will print the first field ($1
).//
markers, you can match against regexes contained in variables with ~
, as in $0 ~ some_variable
. Ranges can be specified as usual with that.-v
option is no exception.So, putting it all together, you could do it like this:
awk -v SS="$2" -v SE="$3" -v TRE="$4" -v RE="$5" '$0 ~ SS,$0 ~ SE { gsub(TRE, RE) } { print }' "$1"
Where the awk code is
$0 ~ SS, $0 ~ SE { # between lines that match SS and SE,
gsub(TRE, RE) # replace stuff that matches TRE with RE
}
{ print } # and print everything.
Upvotes: 2