Regex sed命令替换大括号内的数据
我有一个包含以下数据的文件:Regex sed命令替换大括号内的数据,regex,bash,sed,Regex,Bash,Sed,我有一个包含以下数据的文件: 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命令来搜索整个块,并用字符串替换它
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命令来搜索整个块,并用字符串替换它
我目前有:
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活动字符
让我们以这个示例文件为例:
$ 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...
工作原理:
这将为awk变量-v x=“更换”
分配一个字符串。请注意,使用x
是安全的,因为x=“$2”
是否包含awk活动字符无关紧要x
每当我们遇到起点时,将变量/upstream[:space:]+fibonacci[[:space:]+\{/{f=1}
设置为1(true)f
如果!f{print}
为非真,则打印当前行f
如果当前行包含/}/{print x;f=0}
,则打印}
,并将x
设置回零(false)f
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
)。如果不向后分支,我们将用shell变量ba
的值替换所有模式空间r
$r
当然可以替换为$2
:
sed -E ":a; /upstream[[:space:]]+fibonacci[[:space:]]+\{/{ /}/!{N;ba}; s/.*/$2/ }" file
请注意,如果
$r
(或$2
)包含sed活动字符,则可能会发生意外情况。例如,巧尽心思构建的值可能会导致代码写入文件系统。如果您不确定此变量是否安全,请改用awk代码。sed不适合多行匹配。我将使用perl
use strict;
my $str = '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
}';
my $regex = qr/^upstream\sfibonacci\s{.*}$/msp;
my $subst = '$2';
my $result = $str =~ s/$regex/$subst/rg;
print "The result of the substitution is' $result\n";
对于(带备份的)备份,您可以运行以下命令行:
perl -0777 -i.bak -pe "s/\nupstream\sfibonacci\s{.*}\s*\n/abc/smg" test.txt
sed解决方案可能是:
sed -i '/upstream[[:space:]]fibonacci[[:space:]]{/{:t;N;/}/!bt;s/.*/your_replacement_string/}' your_file_name
/upstream[:space:]]fibonacci[[:space:]{/
只有找到上游斐波那契{,才能执行下一个命令
{/{:t;N;/}/!bt;s/*/您的替换字符串/}
:t
N
bt
将分支回标签t
,并执行N
命令}
,则bt
不会跳回s/*/your\u replacement\u string/
将到达默认情况下,
sed
命令一次只能处理一行。为了让它们处理一组连续的行,您必须在它们前面加上两个地址(并非所有sed
命令都接受两个地址)
地址可以是数字(行号),$
(输入中的最后一行)或分隔的正则表达式。具有两个地址的命令行选择一个包含范围。此范围从与第一个地址匹配的第一个模式空间开始。该范围的结尾是与第二个地址匹配的下一个模式空间
理论已经足够了,让我们编写一个sed
命令:
sed -i -e "/^upstream fibonacci/,/}/c\\
$2" testfile.sh
是的,该命令跨越两行,它没有被错误包装或出于可读性考虑
所使用的是c
,它期望替换字符串从下一行开始。sed
表达式以$2
后面的引号结束
如果shell是bash
,则可以使用$'\n'
在命令中插入新行:
sed -i -e "/^upstream fibonacci/,/}/c\ "$'\n'"$2" testfile.sh
它的工作原理
sed
命令是c
。其文档说明:
将所选行替换为文本
,其中每个嵌入的换行符前面都有反斜杠
它前面有两个正则表达式地址:/^upstream fibonacci/
是范围的开始,/}/
是范围的结束。每个范围从一行开始,该行以上游斐波那契
开头,并以包含右括号(}
)的起始行之后的第一行结束
整个范围将替换为作为参数传递给
c
命令的文本。Wow,谢谢!我以前没有用过awk。我肯定会把它加入我的兵工厂。@mcdito13不客气。另外,为了比较,我刚刚用sed
code更新了答案。谢谢!我以前没有尝试过perl。根据谷歌的说法,这对regex很好。肯定会学到一些。为什么你从来没有投票并接受过任何答案?你评论说他们对你很有帮助。。。
c \
text