Issue
I need to search and replace a pattern from file
[ec2_server]
server_host=something
[list_server]
server_host=old_name
to
[ec2_server]
server_host=something
[list_server]
server_host=new_name
I'm able to get it working with
awk '/\[list_server]/ { print; getline; $0 = "server_host=new_name" } 1'
But I'm trying to parameterize the search pattern, the parameter name to change and the parameter value to change.
PATTERN_TO_SEARCH=[list_server]
PARAM_NAME=server_host
PARAM_NEW_VALUE=new_name
But it is not working when I parameterize and pass the variables to awk
awk -v patt=$PATTERN_TO_SEARCH -v parm=$PARAM_NAME -v parmval=$PARAM_NEW_VALUE '/\patt/ { print; getline; $0 = "parm=parmval" } 1' file.txt
Solution
You have two instances of the same problem: you're trying to use a variable name inside a string value. Awk can't read your mind: it can't intuit that sometimes when your write "HOME" you mean "print the value of the variable HOME" and other times you mean "print the word HOME".
We need to make two separate changes:
First, to use a variable in your search pattern, you can use syntax like this:
awk -v patt='some text' '$0 == patt {print}'
(Note that here we're using an equality match, ==
; you can also use a regular expression match, ~
, but in this particular case that would only complicate things).
With your example file content, running:
awk -v patt='[list_server]' '$0 == patt {print}' file.txt
Produces:
[list_server]
Next, when you write $0 = "parm=parmval"
, you're setting $0
to the literal string parm=parmval
. If you want to perform variable substitution, consider using sprintf()
:
awk \
-v patt="$PATTERN_TO_SEARCH" \
-v parm="$PARAM_NAME" \
-v parmval="$PARAM_NEW_VALUE"\
'
$0 == patt { print; getline; $0 = sprintf("%s=%s\n", parm, parmval) } 1
' file.txt
Which gives us:
[ec2_server]
server_host=something
[list_server]
server_host=new_server
Answered By - larsks Answer Checked By - David Goodson (WPSolving Volunteer)