Bash 用sed替换带有缩进的文本块
我有下一个代码:Bash 用sed替换带有缩进的文本块,bash,sed,Bash,Sed,我有下一个代码: echo -e ' aaa\nddd\nddd\n bbb' | sed -re ':x; N; $!b x; s/(^|\n)(\s*)(aaa)\n(.*?)\n\2(bbb)(\n|$)/\1\2\3\n\2ccc\n\2\5\6/g' 该代码将aaa和bbb之间的所有内容替换为ccc。此外,它还使用它找到的相同缩进: fff aaa ddd ddd bbb fff 将被处理为 fff aaa ccc bbb fff 但
echo -e ' aaa\nddd\nddd\n bbb' | sed -re ':x; N; $!b x; s/(^|\n)(\s*)(aaa)\n(.*?)\n\2(bbb)(\n|$)/\1\2\3\n\2ccc\n\2\5\6/g'
该代码将aaa和bbb之间的所有内容替换为ccc。此外,它还使用它找到的相同缩进:
fff
aaa
ddd
ddd
bbb
fff
将被处理为
fff
aaa
ccc
bbb
fff
但有一个问题。我无法将其移植为使用我的变量:
sed -ire ":x; N; $!b x; s@(^|\n)(\s*)(${START})\n(.*?)\n\2(${STOPSEQREG})(\n|$)@\1\2\3\n\2${ENUMARRAY[$i]}\n\2\5\6@g" $f
START: /* R+ Testy */ (with escaped / & *)
STOPSEQREG: /* R- */ (with escaped / & *)
ENUARRAY[i]: case AAA:\n break;
START,STOPSEQREG&ENUMARRAY[i]包含/,*,空格,:,;,+及-。数组的元素还包含\n。/&*符号用\转义
运行时显示的错误是“错误的反向引用”
谁能帮帮我吗
提前谢谢
p.S.变量示例:
sed -ire ":x; N; $!b x; s@(^|\n)(\s*)(${START})\n(.*?)\n\2(${STOPSEQREG})(\n|$)@\1\2\3\n\2${ENUMARRAY[$i]}\n\2\5\6@g" $f
START: /* R+ Testy */ (with escaped / & *)
STOPSEQREG: /* R- */ (with escaped / & *)
ENUARRAY[i]: case AAA:\n break;
我发现了几件事:
- 您需要在sed脚本中引用
s,因为BASH可能会首先到达那里,并将它们解释为空变量。因此,不要使用$
和$!b
,试试(\n |$)
和\$!b
(\n | \$)
- 有可能简化正则表达式,例如不能将
简化为(.*)
(.+)
- …但最重要的是,不要将
与(GNU)sed一起使用。-ire
被用作r
(备份)的一个参数,因此您的正则表达式被视为基本正则表达式,它需要每个括号都被转义,并且不支持-i
等。这就是为什么sed认为没有捕获的组。改用\s
。请参阅,还有这个问题:-i-re
概述:对于这种复杂的东西,我个人总是希望使用一种具有良好正则表达式和shell支持的语言,例如Python/Perl/Ruby/Groovy等。这避免了BASH(或其他shell)/SED引用地狱怪癖和问题,允许进行单元/集成测试/调试和日志记录,但有时显然会带来自己的负担,或者,不幸的是,这并不总是可能的。您能提供使用带有可变赋值的
sed
的脚本吗?完整脚本:以下是测试文件:源:和目标:1)我应该使用什么来代替-ire?2) 我尝试过反斜杠$符号或使用Cometing,比如;"'$'"!b
但它仍然不起作用。哦,是的,应该加上这个。。。看我更新的答案!(简而言之,-i-re
)下面是代码现在的样子:sed-i-re:x;N;\$!bx;s@(^|N)(\s*)(${START})\N(.+)\N\2(${STOPSEQREG})(\N|\$)\1\2\3\N\2${ENUMARRAY[$i]}\N\2\5\6@g“$f
但该代码不能替代任何东西。完整脚本:第一步是停止错误,这是一个好的开始。正确使用正则表达式完全是另一个问题;我要做的(除了使用另一种语言——见上文)是预先将正则表达式构建为字符串,并将其回显到控制台。这样,您就可以使用一些有用的工具,如www.regexr.com来调试regex,并使用您的输入进行测试。顺便说一句,我不确定它的目的是什么,但我怀疑你希望\2
在\n
之后,在之前(${STOPSEQREG})
(在LHS上)。另外,我假设您仅在这里使用UNIX行结尾(\n
),否则您需要重新考虑一些内容。