用sed递归替换文本

recursively replace text with sed

我想使用 sed 替换完整源文件树中特定文本的每次出现。我尝试了以下操作: $ grep -rlI name2port\(\"Wan1\"\) . --exclude-dir=.svn --exclude=*.vxs | xargs sed -i 's/name2port\(\"Wan1\"\)/T_PORT_ID_WAN1/g' 但它似乎不起作用,我认为我的 sed cmd 不正确。
我该怎么做?

问题是,替换并没有发生。

我试过这个:$ sed -i 's/name2port\(\"Wan1\"\)/T_PORT_ID_WAN1/g' ./rtos_core/jpax_switch/api/src/nms/switch_l3_route.c 但事实证明,name2port("Wan1") 的出现不会被替换。

sed 默认使用 BRE( 基本 正则表达式),出于历史原因,这对某些人来说令人惊讶用于现代正则表达式 - 需要 转义 某些 元字符才能被识别。

在 BRE 中,()普通(字面)字符,并且只变得特殊当 \-转义时。

因此,要匹配文字 name2port("Wan1"),请在 BRE 中按原样使用该文字 (前提是您也不需要 \ -escape " 实例):

sed -i 's/name2port("Wan1")/T_PORT_ID_WAN1/g' ./rtos_core/jpax_switch/api/src/nms/switch_l3_route.c

如果你不关心便携性,你可以使用-r(或者-E for limited 可移植到 macOS,尽管 -i 不起作用),然后 启用 ERE( 扩展 正则表达式),其语法和功能更可能会如您所愿:

sed -r -i 's/name2port\("Wan1"\)/T_PORT_ID_WAN1/g' ./rtos_core/jpax_switch/api/src/nms/switch_l3_route.c

注意文字 () 现在 do 需要 \ 转义,以免它们被解释为包含捕获组.

在这种特殊情况下,BRE 比 ERE 需要更少的转义;不过,通常情况恰恰相反。