最终目标是用^^替换^ NULL ^的所有实例。对于这个问题,为了提高可读性,我将尝试用^ fred ^替换^ NULL ^。这是我的测试数据。
/usr/redbrick_dir $ cat temp
a^NULL^b^c^
e^NULL^NULL^f^
g^h^i^NULL^
这是我期望的工作。
/usr/redbrick_dir $ cat temp | sed "s/\^NULL\^/\^fred\^/g"
a^fred^b^c^
e^fred^NULL^f^
g^h^i^fred^
请注意,在第2行中,仅替换^ NULL ^的第一个实例。但是,如果我只使用一个分隔符运行命令,
/usr/redbrick_dir $ cat temp | sed "s/NULL\^/fred\^/g"
a^fred^b^c^
e^fred^fred^f^
g^h^i^fred^
我得到了理想的结果。如果我只使用尾随分隔符,我也会得到这些结果。问题是,为什么这个命令只替换^ NULL ^?
的第一个实例cat temp | sed "s/\^NULL\^/\^fred\^/g"
编辑从此处开始
以下是我尝试下面发布的几个答案时发生的事情。
cat temp | sed "s/(?<=\^)NULL(?=\^)/fred/g"
a^NULL^b^c^
e^NULL^NULL^f^
g^h^i^NULL^
cat temp | sed ":a s/\^NULL^/^fred^/;ta"
sed: 0602-417 The label :a s/\^NULL^/^fred^/;ta is greater than eight characters.
我必须查看Utopik提供的链接。
答案 0 :(得分:2)
为什么这个命令只替换^ NULL ^?
的第一个实例
因为表达式与第二行中的第二个^NULL^
不匹配,所以在表达式找到第一个^NULL^
之后,它现在尝试在{{1}之后的字符处找到匹配项}:
^
我不知道e^NULL^ NULL^f^
^
it is now trying to find a match here but there is no ^NULL^ here, there is NULL^ only.
是否支持lookbehinds或lookaheads,但如果确实如此,那么我会做这样的替换:
sed
或者在你的情况下,当然用空字符串替换cat temp | sed "s/(?<=\^)NULL(?=\^)/fred/g"
。
答案 1 :(得分:2)
使用GNU sed
进行测试首先,您可以删除一些反斜杠:sed "s/\^NULL^/^fred^/g"
而不做任何更改(^
没有任何意义,但在正则表达式开始时)
然后,sed将匹配^NULL^
,并且该匹配中的任何字符都不能重复用于另一场比赛。因此,它无法与第二个^NULL^
匹配,只能与NULL^
匹配,这就是它无效的原因。
你可以这样做:
sed ":a s/\^NULL^/^fred^/;ta"
为什么?因为它将替换第一个^NULL^
,然后反复重新启动替换直到不再发生替换,并且因为它是一个新的替换循环,所以每个字符都可以匹配
$ cat temp
a^NULL^b^c^
e^NULL^NULL^NULL^NULL^NULL^NULL^NULL^NULL^NULL^f^
g^h^i^NULL^
$ cat temp | sed ":a s/\^NULL^/^fred^/;ta"
a^fred^b^c^
e^fred^fred^fred^fred^fred^fred^fred^fred^fred^f^
g^h^i^fred^
没关系。
答案 2 :(得分:2)
There are two different scenarios:-
1) In First sed command it is like that
sed "s/\^NULL\^/\^fred\^/g"
当它到达第二行时。正在搜索两个字符串,因为第一个是^ NULL ^,第二个是NULL ^。所以这里无与伦比。因此,它不会取代相同的。例如sed是如何搜索单词的 搜索单词替换单词 发现^ Null ^ ^ fred ^ 找不到Null ^
2) In second sed command it is like that sed "s/NULL\^/fred\^/g"
这里只搜索单词Null ^并替换为fred ^。所以它正确地匹配了这个词。