我可以将字符串替换限制为与正则表达式匹配的行的一部分吗?
例如:
A this matches Z this does not
并且,我想将this
替换为that
,但仅限于匹配的子字符串:
A[^Z]*Z
也就是说,可以操作的线的唯一部分如下面粗体所示:
这匹配Z 这不是
所以,我正在寻找结果:
A that matches Z this does not
但是,请查看我尝试在整条线路上运行的实际结果:
% sed '/A[^Z]*Z/ {
s/this/that/g
}' <<<"A this matches Z this does not"
A that matches Z that does not
%
以上示例仅供参考。
回顾:是否有使用sed
的常规解决方案仅将更改到一行的正则表达式匹配部分?如果答案是&#34;否,&#34;那么有一个解决方案只使用安装在CentOS 7最小配置中的软件(例如awk
)吗?另外,我不想依赖第三方软件包。
我的环境:
答案 0 :(得分:1)
您可以使用带有捕获组的正则表达式来匹配所需行的部分,并仅替换其中的一部分。
sed 's/\(A[^Z]*\)this\([^Z]*Z\)/\1that\2/'
答案 1 :(得分:1)
使用以下方法:
echo "A this matches Z this does not" | sed -r 's/(A[^Z]*)\bthis\b([^Z]*Z)/\1that\2/g'
输出:
A that matches Z this does not
答案 2 :(得分:1)
如果perl
可用:
$ echo 'A this matches Z this does not' | perl -pe 's/A[^Z]*Z/$&=~s|this|that|gr/ge'
A that matches Z this does not
g
修饰符,用于替换所有匹配文本。e
评估修饰符允许在替换$&=~s|this|that|gr
表达式仅在匹配的文字中执行替换,r
修饰符会在不更改$&
的值的情况下返回结果进一步阅读:
答案 3 :(得分:0)
如果您只能使用sed,则可以使用bash完成:
#!/bin/bash
str="This does not A this matches Z this also does not"
regex='^\(.*\)\(A[^Z]*Z\)\(.*\)$'
a=$(sed -e 's/'"$regex"'/\1/' <<<"$str")
b=$(sed -e 's/'"$regex"'/\2/' -e 's/this/that/g' <<<"$str")
c=$(sed -e 's/'"$regex"'/\3/' <<<"$str")
echo "$a$b$c"
或者,您可以使用awk(更快):
#!/bin/bash
str="This does not A this matches Z this also does not"
awk -vreg='A[^Z]*Z' '{
split($0,a,reg,s);
printf("%s%s%s\n",a[1],gensub(/this/,"that","g", s[1]),a[2])
}' <<<"$str"