2

我正在尝试替换属性文件中的一行文本。例如:

food.type=banana

使用这行代码,我可以用另一个输入的输入完全替换香蕉。

FOOD=apple
sed "s/food.type=.*/food.type=$FOOD/" 

输出:

food.type=apple

但是,当我尝试替换的前一行文本中有一个/时,我无法让替换工作。例如:

food.type=/yellow/banana

任何帮助深表感谢。谢谢!

4

2 回答 2

5

斜杠被解读为关闭正则表达式匹配/替换模式,

sed "s@food.type=.*@food.type=$FOOD@" 

一些 sed 要求您转义非标准分隔符的第一个实例,即

sed "s\@food.type=.*@food.type=$FOOD@" 

我希望这有帮助。

于 2012-05-21T17:03:56.620 回答
1

另一种选择是继续/用作 sed 的分隔符,并转义替换字符串中的任何斜线。bash 可以做到这一点(虽然它很神秘):

sed "s/food.type=.*/food.type=${FOOD//\//\/}/"

那个变量替换是相当神秘的,所以让我把它分解解释一下:

${FOOD 开始一个 FOOD 的变量替换,用...
// 替换所有出现
\/ 的字符/(注意它必须在此上下文中转义)
/ 替换
\/ 字符串\/(注意这里的转义被简单地视为替换字符串的一部分)替换
} 结束

但这并不完全完美,因为如果替换字符串中出现其他几个字符可能会导致问题。要真正做到这一点,您可以在 bash 中进行多次替换(混乱),或者将工作外包给sed

ESCAPEDFOOD="$(printf "%s" "$FOOD" | sed 's/[\/&]/\\&/g')"
sed "s/food.type=.*/food.type=$ESCFOOD/"

同样,替换有点神秘,所以这里有一个细分:

s/ 替换模式
[\/&] 中的任何字符\,/&
/ ...
\\& 替换字符串\(此处转义)后跟原始匹配
/g ...全局(即替换所有出现)

(是的,我知道使用sed来准备与 . 一起使用的字符串具有讽刺意味sed。)

请注意,我可能错过了一些麻烦的字符;如果是这样,它们可以添加到[]表达式中。

于 2012-05-21T21:50:57.557 回答