![查找并替换两个定界符之间的字符串](https://linux22.com/image/723380/%E6%9F%A5%E6%89%BE%E5%B9%B6%E6%9B%BF%E6%8D%A2%E4%B8%A4%E4%B8%AA%E5%AE%9A%E7%95%8C%E7%AC%A6%E4%B9%8B%E9%97%B4%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2.png)
如何替换两个定界符之间的字符串?
我找到的一些答案很接近,但我认为我的需求稍微复杂一些。
即smb.conf
共享之间有一个空白行。我想定位要更新的共享。第一个分隔符是“[sharename]”,最后一个分隔符可以是空白行。
我想查找并将“writable = yes”替换为“writable = no”,由于空格,它可能格式不准确,但必须出现在我的两个分隔符之间。
答案1
几乎已经完成了,感谢这份清单和 http://fahdshariff.blogspot.com/2012/12/sed-mutli-line-replacement-between-two.html。
我可以在命令行上用“# writeable”替换“writeable”,并且可以不考虑 Y/N 设置而这样做,稍后我会插入另一行。
sed '/\[${share_name}\]/,/^$/{/\[${share_name}\]/n;/^$/!{s/writeable/\#writeable/g}}' \
< ${input_file} \
> /tmp/parse-smb.tmp
虽然这在命令行上使用“!”转义的“!”有效,但在脚本文件 /bin/sh 中无效。我必须删除转义,但触发器不会命中。
外壳的微妙之处。
答案2
啊,“!”没问题,这是“share_name”变量转换失败。在此命令中使用双引号而不是单引号。
sed "/\${share_name}\]/,/^$/{/[${share_name}\]/n;/^$/!s/writeable/\#writeable/g}}" \
< ${input_file} \
> /tmp/parse-smb.tmp
应该意识到后续行也使用了双引号。
sed -i "s/\[${share_name}\]/\[${share_name}\]\n\thosts allow = 10.50.157.0\/24 \n\twriteable = no/" \
/tmp/parse-smb.tmp
答案3
我认为 perl:未经测试
perl -00 -pe '/^\[your_share_name\]/ and s/writable\s*=\s*\Kyes/no/si' smb.conf
答案4
我认为这是 perl 的工作(或者如果你愿意的话,也可以是 python。)
iMac$ cat ./replace.pl
#!/usr/bin/perl
while (<>) {
if (/^\n/) { $replace = 0; }
if (/\[share3\]/) { $replace = 1; }
print unless /writable/;
if (/writable/) {
if ($replace == 1) {
print " writable = no\n";
}
else {
print;
}
}
}
iMac$ cat smb.conf
[share1]
writable = yes
user = anonymous
host = remote
[share2]
writable = yes
user = anonymous
host = remote
[share3]
writable = yes
user = anonymous
host = remote
[share4]
writable = yes
user = anonymous
host = remote
[share5]
writable = yes
user = anonymous
host = remote
iMac$ cat smb.conf | ./replace.pl
[share1]
writable = yes
user = anonymous
host = remote
[share2]
writable = yes
user = anonymous
host = remote
[share3]
writable = no
user = anonymous
host = remote
[share4]
writable = yes
user = anonymous
host = remote
[share5]
writable = yes
user = anonymous
host = remote