我试图使用sed来清理url行来提取域。

所以从:

http://www.suepearson.co.uk/product/174/71/3816/

我想要:

http://www.suepearson.co.uk/

(不管后面有没有斜杠,都没有关系)

我试过:

 sed 's|\(http:\/\/.*?\/\).*|\1|'

And(转义非贪婪量词)

sed 's|\(http:\/\/.*\?\/\).*|\1|'

但我似乎不能让非贪婪量词(?)工作,所以它总是匹配整个字符串。


当前回答

因为您特别指出您正在尝试使用sed(而不是perl、cut等),所以请尝试分组。这就避免了非贪婪标识符可能无法被识别。第一组是协议(即协议)。'http://', 'https://', 'tcp://',等等)。第二组是域:

echo "http://www.suon.co.uk/product/1/7/3/" | sed "s|^\(.*//\)\([^/]*\).*$|\1\2|"

如果您不熟悉分组,请从这里开始。

其他回答

sed -E将正则表达式解释为扩展(现代)正则表达式

更新:MacOS X为-E, GNU sed为-r。

Sed不支持“非贪婪”操作符。

你必须使用“[]”操作符来排除“/”匹配。

sed 's,\(http://[^/]*\)/.*,\1,'

附注:不需要反斜杠"/"。

还没有看到这个答案,所以这里是如何用vi或vim做到这一点:

vi -c '%s/\(http:\/\/.\{-}\/\).*/\1/ge | wq' file &>/dev/null

这将全局运行vi:%s替换(后面的g),如果没有找到模式,则避免引发错误(e),然后将结果更改保存到磁盘并退出。&>/dev/null可以防止GUI在屏幕上短暂闪烁,这很烦人。

有时候我喜欢用vi来处理超级复杂的正则表达式,因为(1)perl已经奄奄一息了,(2)vim有一个非常先进的正则表达式引擎,(3)在我日常使用的编辑文档中,我已经非常熟悉vi正则表达式了。

这可以使用cut:

echo "http://www.suepearson.co.uk/product/174/71/3816/" | cut -d'/' -f1-3

由于这里也标记了PCRE,我们可以通过在regex中使用非惰性匹配来使用GNU grep。它将匹配与。*相对的第一个最近的匹配(它实际上是贪婪的,直到匹配的最后一次出现)。

grep -oP '^http[s]?:\/\/.*?/' Input_file

解释:此处使用grep的oP选项,其中-P负责启用PCRE正则表达式。在grep的主程序中提到regex,它匹配开始http/https,后面跟着://直到下一次出现/,因为我们已经使用了。*?它将查找first / after (http/https://).它只打印匹配的部分。