如何使用 sed 替换文件中的复杂行?
例如,我想替换 /etc/udev/rules.d/70-persistent-net.rules 中的 udev 规则。
这不起作用:
OLD_RULE='SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="52:54:00:36:4c:e5", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"'
NEW_RULE='SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="52:54:00:36:4c:e5", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"'
sed -i "s/$OLD_RULE/$NEW_RULE/g" /etc/udev/rules.d/70-persistent-net.rules
该文件保持不变。
答案1
您将需要转义 OLD_RULE 中可以解释为模式魔术字符的所有字符。或者更简单地说,使用模式来匹配您想要操作的行,然后仅执行您实际需要的最少替换。
也许类似(未经测试)sed -i '/, NAME="eth1"/s/eth1/eth0/' /etc/udev/rules.d/70-persistent-net.rules
。
答案2
有时可能有效的方法(在这个特定示例中有效)是使用 的printf
引用能力 和sed -r
:
old_rule='SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="52:54:00:36:4c:e5", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"'
new_rule='SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="52:54:00:36:4c:e5", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"'
printf -v sed_repl 's/%q/%q/g' "$old_rule" "$new_rule"
sed -r -i "$sed_repl" /etc/udev/rules.d/70-persistent-net.rules