我试图使用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|'

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


当前回答

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

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

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

其他回答

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

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

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

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

克利斯朵夫·西格哈特(Christoph Sieghart)著

在sed中获得非贪婪匹配的技巧是匹配除终止匹配的字符外的所有字符。我知道,这很简单,但我在这上面浪费了宝贵的时间,毕竟shell脚本应该是快速而简单的。所以以防别人需要

贪婪匹配

% echo "<b>foo</b>bar" | sed 's/<.*>//g'
bar

非贪婪匹配

% echo "<b>foo</b>bar" | sed 's/<[^>]*>//g'
foobar

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

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

使用纯(GNU) sed仍然有希望解决这个问题。尽管这不是一个通用的解决方案,在某些情况下,你可以使用“循环”来消除字符串中所有不必要的部分,就像这样:

sed -r -e ":loop" -e 's|(http://.+)/.*|\1|' -e "t loop"

-r:使用扩展的正则表达式(用于+和未转义的括号) 定义一个名为"loop"的新标签 -e:在sed中添加命令 "t loop":如果有成功的替换,则跳回标记"loop"

这里唯一的问题是它也会切掉最后一个分隔符('/'),但如果你真的需要它,你仍然可以在“循环”结束后简单地把它放回去,只需要在前面的命令行末尾追加这个额外的命令:

-e "s,$,/,"

以下是你可以用两步方法和awk完成的事情:

A=http://www.suepearson.co.uk/product/174/71/3816/  
echo $A|awk '  
{  
  var=gensub(///,"||",3,$0) ;  
  sub(/\|\|.*/,"",var);  
  print var  
}'  

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

希望有帮助!