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

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


当前回答

我知道这是一个旧条目,但有人可能会发现它有用。 由于完整域名的总长度不超过253个字符,请将。*替换为。\{1,255 \}

其他回答

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

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

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

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

-e "s,$,/,"

这可以使用cut:

echo "http://www.suepearson.co.uk/product/174/71/3816/" | cut -d'/' -f1-3
echo "/home/one/two/three/myfile.txt" | sed 's|\(.*\)/.*|\1|'

别麻烦了,我在另一个论坛上看到的:)

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

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

贪婪匹配

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

非贪婪匹配

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

在这种特定情况下,您可以在不使用非贪婪正则表达式的情况下完成工作。

试试这个非贪婪的正则表达式[^/]*来代替。*?:

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