如何在sed命令中使用bash变量?

时间:2015-09-16 15:58:32

标签: bash sed

我想做(在bash脚本中):

NEWBASE=`echo $NAME | sed "s/${DIR}//g" | sed 's/.\///g'`

我在网上看到,我必须用双引号替换单引号。
遗憾的是,这不起作用。为什么?
谢谢

2 个答案:

答案 0 :(得分:1)

sed对此有点矫枉过正。使用参数扩展:

NEWBASE=${NAME//$DIR//}
NEWBASE=${NEWBASE//.\//}

答案 1 :(得分:0)

重要的是要理解bash和sed是两个完全独立的东西。当你给bash一个命令时,它首先根据它的规则处理它,以便为该实用程序(在本例中为sed)提供实用程序名称和一组参数,然后使用参数调用该实用程序。 / p>

可能$DIR包含斜杠字符。也许它看起来像/usr/home/codyline/src

所以当bash将其替换为sed命令的参数时:

"s/${DIR}//g"

结果是

s//usr/home/codyline/src//g

然后传递给sed。但是sed无法理解commabnd:它有(很多) / 字符。

如果您真的想为此目的使用sed,则需要使用 / 以外的分隔符,并且它必须是您自信永远不会出现在$DIR中的字符。幸运的是,sed s命令允许您将任何字符用作分隔符:s后面的任何字符都用作分隔符。但是在命令中总是必须有三个。

例如,您可能认为没有目录路径包含冒号(),在这种情况下您可以使用:

sed "s:${DIR}::g"

当然,总有一天会因为你的名字中有一个冒号的目录而失败。因此,通过使用bash的替换和替换功能来反斜杠 - 逃脱所有冒号,你可以使事情变得更加通用:

sed "s:${DIR//:/\:}::g"

但你可以使用这个bash功能,以避免完全使用sed:

NEWBASE=${NAME//$DIR}

不幸的是,你无法嵌套bash替换和替换,所以你需要按顺序执行它们:

NEWBASE=${NEWBASE//.\/}

注意:我使用${var//...},这相当于在sed g命令中指定s标志,但我真的不知道它是否合适。您真的希望在一条路径中有多个$DIR个实例吗?如果有多个实例,您真的想要删除所有实例吗?你必须做出决定。