Maax
Maax

Reputation: 33

sed is not working from inside bash

I'm trying to use sed to replace ${SRC} and ${MSG} from external files. Both of them are variables that are available in following bash script.

#!/bin/bash

SRC=$1
DST=$2
MSG=$3
CONN=$4
GROUP=$5


echo "$SRC","$DST","$MSG","$CONN","$GROUP" >> /home/maaz/smpp/smppin/incoming.log

/usr/bin/sed -i -e "s/\${SRC}/$SRC/" -e "s/\${MSG}/$MSG/" request.xml >> request.xml

File request.xml looks like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:SendSMS>
        <!--Optional:-->
         <tem:Number>${SRC}</tem:Number>
         <!--Optional:-->
         <tem:AccountID>${MSG}</tem:AccountID>
      </tem:SendSMS>
   </soapenv:Body>
</soapenv:Envelope>

I need to replace text ${SRC} and ${MSG} with their corresponding values from bash. At the moment same sed expression is replacing text,if running from outside bash, but no change in file when script is called.

Any assistance will be appreciated.

Upvotes: 0

Views: 128

Answers (3)

Charles Duffy
Charles Duffy

Reputation: 295443

Ignoring that your input file is XML, envsubst is the right tool for substituting placeholders of the form ${foo} with values in an environment variable of that same name.

src=$1; dst=$2; msg=$3; conn=$4; group=$5
tempfile=$(mktemp -t request.xml.XXXXXX)

# to edit request.xml in-place:
SRC=$src DST=$dst MSG=$msg CONN=$conn GROUP=$group envsubst \
  <request.xml >"$tempfile" && mv "$tempfile" request.xml

That said, if we didn't ignore that, and chose to use XML-aware tools, we'd come up with an altogether different solution:

#!/bin/bash
SRC=hello
MSG=world
tempfile=$(mktemp request.xml.XXXXXX)
xmlstarlet ed -u '//*[.="${SRC}"]' -v "$SRC" \
              -u '//*[.="${MSG}"]' -v "$MSG" \
  <request.xml >"$tempfile" && mv "$tempfile" request.xml

...yields, given your input file:

<?xml version="1.0"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
  <soapenv:Header/>
  <soapenv:Body>
    <tem:SendSMS>
      <!--Optional:-->
      <tem:Number>hello</tem:Number>
      <!--Optional:-->
      <tem:AccountID>world</tem:AccountID>
    </tem:SendSMS>
  </soapenv:Body>
</soapenv:Envelope>

...and is guaranteed to result in output that's in valid XML format, even if the strings to be substituted need to be escaped or otherwise modified to be valid in XML.

Upvotes: 3

sjsam
sjsam

Reputation: 21965

Below script will do:

dst=$2 # Uppercase variables are usually reserved for the system
msg=$3 # So use lowercase variables for your scripts like 'dst','msg' and so
.
.
.
sed -E -i 's/\$\{SRC\}/'"$src"'/g;s/\$\{MSG\}/'"$msg"'/g' request.xml

Notes

  1. The inplace edit option -i makes the change effective in the file.
  2. You should never do request.xml >> request.xml ie read from and write to the file simultaneously
  3. There is no harm in double quoting the variables (eg SRC="$1"). This will prevent word splitting in the variables.
  4. The -E option with sed is more portable and recognized with most of the sed versions these days.

Edit
If extended regular expressions are not enabled, you could write the sed statement like below :

sed -i 's/\${SRC}/'"$src"'/g;s/\${MSG}/'"$msg"'/g' request.xml

Upvotes: 0

Shadowfen
Shadowfen

Reputation: 469

Check if sed path /usr/bin/sed on your system. It's /bin/sed on mine.

Upvotes: 0

Related Questions