在sed
我希望能够匹配/js/
但不能/js/m
我无法匹配/js/[^m]
,因为这会匹配/js/
加上任何角色来后。负向前看在sed
中不起作用。或者我会做/js/(?!m)
并称它为一天。有没有办法用sed来实现这个目的,这种方法适用于大多数类似的情况,你想要一段不在另一段文本中结束的文本?
对于我想做的事情,有没有比sed更好的工具?可能是一个允许向前看的人。 awk
使用自己的语言似乎有点太多了。
答案 0 :(得分:2)
嗯,你可以这样做:
$ echo 'I would like to be able to match /js/ but not /js/m' |
sed 's:@:@A:g; s:/js/m:@B:g; s:/js/:<&>:g; s:@B:/js/m:g; s:@A:@:g'
I would like to be able to match </js/> but not /js/m
当你找到/ js /时,你没有说出你想做什么,所以我只是把<>
放在它周围。这将适用于所有UNIX系统,不像perl解决方案,因为不保证perl可用,并且不保证你可以安装它。
我上面使用的方法是sed,awk等中常见的习惯用法,用于创建输入中不存在的字符串。只要在您真正感兴趣的字符串或正则表达式中没有出现@
,/js/
使用哪个字符并不重要。 s/@/@A/g
确保输入中@
的每次出现后跟A
。所以现在当我s/foobar/@B/g
foobar
时,我已用@B
替换@B
的每一次出现,我知道每个foobar
代表@
,因为所有其他A
s/foo/whatever/
}后跟foo
。所以现在我可以foobar
而不会跳过s/@B/foobar/g; s/@A/@/g
中出现的sed 's:/js/m:\n:g; s:/js/:<&>:g; s:\n:/js/m:g'
。然后我用\n
解开最初的替换。
在这种情况下,虽然您没有使用多行保留空间,但您可以更简单地使用:
sed 's:/js/m:\
:g; s:/js/:<&>:g; s:\
:/js/m:g'
因为换行符分隔的字符串中不能有换行符。以上内容仅适用于支持使用T(n) = 2T(n-1)
表示换行符(例如GNU sed)的seds,但是对于所有seds的可移植性应该是:
O(2^n)