• Uncategorized

About bash : How-to-use-variables-in-sed-command

Question Detail

I have file called “text_file1.txt” and the content in the file is
“subject= /C=US/O=AAA/OU=QA/OU=12345/OU=TESTAPP/”

Now what i want to achieve is to the content to be like below:
“subject= /C=US/O=AAA/$$$QA/###12345/@@@TESTAPP/”

when i execute the below piece of code:

#! /bin/ksh
`sed -i "s/OU=$OU1/$$$\${OU1}/g" text_file1.txt`
`sed -i "s/OU=$OU2/###\${OU2}/g" text_file1.txt`
`sed -i "s/OU=$OU3/@@@\${OU3}/g" text_file1.txt`
content=`cat text_file1.txt`
echo "content:$content"

i get the output like this:

content:subject= /C=US/O=Wells Fargo/2865528655{OU1}/###12345/@@@TESTAPP/CN=03032015_CUST_2131_Unix_CLBLABB34C02.wellsfargo.com

only this command “sed -i "s/OU=$OU1/$$$\${OU1}/g" text_file1.txt” is not working as expected.Can anyone please suggest some idea on this?

Thanks in advance.

Question Answer

Two things play into this:

  1. You have to escape $ (i.e., use \$) in doubly-quoted shell strings if you want a literal $, and
  2. \ does not retain its literal meaning when it comes before a $ inside backticks (that is to say, inside backticks, \$ becomes just $).

When you write

`sed -i "s/OU=$OU1/$$$\${OU1}/g" text_file1.txt`

because the command is in backticks, you spawn a subshell with the command

sed -i "s/OU=$OU1/$$$${OU1}/g" text_file1.txt

Since $$$$ is inside a doubly-quoted string, variable expansion takes place, and it is expanded as two occurrences of $$ (the process ID of the shell that’s doing the expansion). This means that the code sed sees is ultimately


…if the process ID of the spawned subshell is 12345.

In this particular case, you don’t need the command substitution (the backticks), so you could write

sed -i "s/OU=$OU1/\$\$\$${OU1}/g" text_file1.txt

However, using shell variables in sed code is always a problem. Consider, if you will, what would happen if OU1 had the value /; e rm -Rf * # (hint: GNU sed has an e instruction that runs shell commands). For this reason, I would always prefer awk to do substitutions that involve shell variables:

cp text_file1.txt text_file1.txt~
awk -v OU1="$OU1" '{ gsub("OU=" OU1, "$$$" OU1) } 1' text_file1.txt~ > text_file1.txt

This avoids code injection problems by not treating OU1 as code.

If you have GNU awk 4.1 or later,

awk -v OU1="$OU1" -i inplace  '{ gsub("OU=" OU1, "$$$" OU1) } 1' text_file1.txt

can do the whole thing without a (visible) temporary file.

Does this help as a start?

echo ''
echo "subject= /C=US/O=AAA/OU=${OU1}/OU=12345/OU=TESTAPP/" \
| sed -e "s|/OU=${OU1}/|/OU=\$\$\$${OU1}/|g"

The result is:

subject= /C=US/O=AAA/OU=$$$QA/OU=12345/OU=TESTAPP/

(You are mixing up the use of $ signs .)

You must be careful when putting $ inside double quotes.

sed -i "s/OU=$OU1/"'$$$'"${OU1}/g" text_file1.txt


$ OU1="QA"
$ echo 'OU=QA' | sed "s/OU=$OU1/"'$$$'"${OU1}/g"

You may also like...

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.