我有一个包含一些数据的文件,如下所示:
upstream fibonacci { # restservers
server 10.128.0.3; # 0
server 10.128.0.5; # 1
server 10.128.0.7; # 2
server 10.128.0.8; # 3
server 10.128.0.10; # 4
}
我正在尝试找出一个 sed 命令来搜索整个 block ,并将其替换为字符串。
我目前有:
sed -i -e "s/upstream[:space:]fibonacci[:space:]\{.*\}/$2/g" testfile.sh
($2 是传递给此 bash 脚本的字符串参数)
这是我的错误
sed: -e expression #1, char 46: Invalid content of \{\}
我仍在学习我的正则表达式,任何帮助都会很棒。谢谢!
编辑:另一种选择是仅替换大括号之间的文本
最佳答案
使用 awk(推荐)
这可以使用 sed 完成,但 awk 是更好的选择。
首先,像 "s/something/$2/"
这样的 sed 命令是非常危险的,除非 $2
的内容被清理掉所有 sed 事件字符。 p>
让我们看一下这个示例文件:
$ cat file
before...
upstream fibonacci { # restservers
server 10.128.0.3; # 0
server 10.128.0.5; # 1
server 10.128.0.7; # 2
server 10.128.0.8; # 3
server 10.128.0.10; # 4
}
after...
使用 awk 进行替换:
$ awk -v x="Replacement" '/upstream[[:space:]]+fibonacci[[:space:]]+\{/{f=1} !f{print} /}/{print x; f=0}' file
before...
Replacement
after...
它是如何工作的:
-v x="替换"
这将一个字符串分配给 awk 变量
x
。请注意,使用x="$2"
是安全的,因为x
是否包含 awk 事件字符并不重要。/upstream[[:space:]]+斐波那契[[:space:]]+\{/{f=1}
每当遇到起始线时,将变量
f
设置为1(true)!f{print}
如果
f
不为true,则打印当前行。/}/{打印 x; f=0}
如果当前行包含
<}
,则打印x
并将f
设置回零(false)。
使用 sed
让我们将替换字符串定义为 shell 变量 r
:
$ r="Replacement"
这是一个用于执行替换的 sed 命令:
$ sed -E ":a; /upstream[[:space:]]+fibonacci[[:space:]]+\{/{ /}/!{N;ba}; s/.*/$r/ }" file
before...
Replacement
after...
它是如何工作的:
:a
这定义了一个标签
a
。/upstream[[:space:]]+fibonacci[[:space:]]+\{/
这与起始字符串匹配。对于匹配的行,将执行以下命令:
/}/!{N;ba}; s/.*/$r/
如果该行包含
}
,那么我们读取下一行 (N
) 并分支回标签a
(ba)。如果我们不返回分支,我们将用 shell 变量
r
的值替换所有模式空间。
如果你愿意,$r
当然可以替换为$2
:
sed -E ":a; /upstream[[:space:]]+fibonacci[[:space:]]+\{/{ /}/!{N;ba}; s/.*/$2/ }" file
请注意,如果 $r
(或 $2
)包含 sed 事件字符,则可能会发生意外情况。例如,特制的值可能会导致代码写入您的文件系统。如果您不确定该变量是否安全,请改用 awk 代码。
关于regex - sed 命令替换大括号内的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46659385/