我需要删除=
字符串中的第二个和第一个/
字符串之间的所有内容,但保留=
原位。我尝试过很多很多事情,最近的一个是
sed -i 's/=[^/]*//
答案1
仅基于文本描述,没有示例输入/输出,我想出了这个:
$ echo "foo=bar=baz/quux" | sed 's/\(.*=.*\)=.*\/\(.*\)/\1=\2/'
foo=bar=quux
这离你想要的有多近?
答案2
开始撰写有关前瞻和后瞻断言的文章,结果发现 sed 不支持它们!这应该可以解决问题:
sed -i 's!\(=[^=]*=\)[^/]*/!\1!'
- 由于我们在正则表达式中使用
/
字符,因此我们将命令分隔符更改s
为!
\(=[^=]*=\)
是一个捕获组,匹配一个=
字符,后跟零个或多个其他字符,后跟另一个=
字符。需要这部分来确保要=
删除的子字符串之前有两个字符,正如您所说的那样[^/]*/
匹配分隔符和第二个分隔符之间的任何内容\1
用与捕获组匹配的任何内容替换整个匹配的字符串\(=[^=]*=\)
答案3
这是一种解决方案perl
$ echo 'foo=bar=baz/quux' | perl -pe 's|^([^=]+=){2}\K[^=/]+/||'
foo=bar=quux
$ echo 'abc=foo=bar=baz/quux' | perl -pe 's|^([^=]+=){2}\K[^=/]+/||'
abc=foo=bar=baz/quux
从上面的示例可以看出,这限制了仅删除从 2nd=
到2nd 的文本/
^([^=]+=){2}\K
从行首开始查找2
非文本序列,=
后跟=
。意味着\K
正向后看,不是替换字符串的一部分[^=/]+/
表示一个或多个=/
以以下字符结尾的非字符/
- 如果发现这样的文本,它将被删除
与相同的解决方案sed
$ echo 'foo=bar=baz/quux' | sed -E 's|^(([^=]+=){2})[^=/]+/|\1|'
foo=bar=quux
$ echo 'abc=foo=bar=baz/quux' | sed -E 's|^(([^=]+=){2})[^=/]+/|\1|'
abc=foo=bar=baz/quux
它不支持前向/后向构造,因此在替换时使用捕获组并反向引用