Bash – Shell: Find and replace word

awkbashshell-scriptstring manipulation

I have a string in my shell script which is in a fixed format : '[STATUS REPORT] PROJECT'.
When user executes my shell script he will be asked to provide a value for 'PROJECT'.

I would like to replace the word 'PROJECT' with the user provide value. For Eg if 'ABCD' was user input:

'[STATUS REPORT] ABCD'

I have two issues:
1: How to tackle special characters like '&' in a project name? For eg:

echo "[STATUS REPORT] PROJECT" |  awk '{ gsub(/PROJECT/, "A&A"); print }' 

and I get the following output:

[STATUS REPORT] APROJECTA

2: My actual shell statement looks like this:

echo "[STATUS REPORT] PROJECT" |  awk '{ gsub(/PROJECT/, $ProjectName); print }'

where $ProjectName stores the project name provided by user. But this doesn't seem to work

How can I get this working properly?

Best Answer

This will solve your 1st issue:

echo "[STATUS REPORT] PROJECT" |  awk '{ gsub(/PROJECT/, "A\\&A"); print }'

(& is a special char in awk substitution: it means "what has been matched". You need to escape if with a \. And as you are in a awk string, your need to put 2 \ to produce one as \ escape the next char as in \n.)

This will solve your 2nd issue:

ProjectName=toto
echo "[STATUS REPORT] PROJECT" |  awk -v "ProjectName=$ProjectName" '{ gsub(/PROJECT/, ProjectName); print }'

(Edit: notice the newly added " around ProjectName=$ProjectName so a space in ProjectName does not break the script.)

But awk is a big tool to perform string substitution, you might want to use sed:

echo "[STATUS REPORT] PROJECT" |  sed -e 's/PROJECT/A\&A/'
ProjectName=toto;
echo "[STATUS REPORT] PROJECT" |  sed -e "s/PROJECT/${ProjectName//\//\\/}/"

(Edit: a / in ProjectName will was breaking the initial solution. I added the escaping of slashes, but some other char(s) still breaks it: &, \1, ... I think plain bash shell bellow is safer.)

or in plain bash shell:

msg="[STATUS REPORT] PROJECT"
echo ${msg//PROJECT/A&A}
ProjectName=toto
echo ${msg//PROJECT/$ProjectName}
Related Question