sed_with_shell_variable

有个事情需要在sed命令中使用shell脚本里的变量,折腾了好久终于解决,在这里记录下解决方案

Sed

Assume we have a text:

1
2
3
# conf
home = /home/user/
dir = ${TargetDir}/bin

and a shell script to replace the ${TargetDir} with the true path:

1
2
3
4
5
6
#!/bin/bash
TargetDir=home
TestDir=lincoln
sed -i `expression` conf

First, recall the sed command with option s

1
sed 's/${TargetDir}/${TestDir}/g'

The string ${TargetDir} will be replaced by string ${TestDir}, which occurs:

1
2
3
# conf
home = /home/user/
dir = ${TestDir}/bin

Two, expand the Variable in sed expression

There are two ways:

  • Add '' around the shell variable need to be expanded.
1
sed 's/${TargetDir}/'${TestDir}'/g'
1
2
3
# conf
home = /home/user/
dir = lincoln/bin
  • Use "" instead of '' around the sed expression to expand all shell variables.
1
sed "s/${TargetDir}/${TestDir}/g"
1
2
3
# conf
home = /lincoln/user/
dir = ${TargetDir}/bin

To un-expand the shell variable, use \$ to escape the translation

1
sed "s/\${TargetDir}/${TestDir}/g"
1
2
3
# conf
home = /home/user/
dir = lincoln/bin

So far so good

The solution 2 and 3 works fine, but when there has / in the variable, an error will occur: sed: -e expression #1, char 10: unknown option to 's', because the expanded expression has too many /. That what confused me this afternoon.

To solve this, just to use # instead of / to separate in the sed expression.

1
sed "s#\${TargetDir}#$TestDir#g"
1
2
3
# conf
home = /home/user/
dir = lincoln/bin