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

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


当前回答

下面的解决方案适用于匹配/使用multiply present(链式;串联;复合)HTML或其他标签。例如,我想编辑HTML代码以删除串联出现的<span>标记。

问题:常规sed正则表达式贪婪地匹配从第一个到最后一个的所有标记。

解决方案:非贪婪模式匹配(每个讨论在这个线程的其他地方;例如,https://stackoverflow.com/a/46719361/1904943)。

例子:

echo '<span>Will</span>This <span>remove</span>will <span>this.</span>remain.' | \
sed 's/<span>[^>]*>//g' ; echo

This will remain.

解释:

S /<span>:查找<span> [^>]:后面跟着不是>的任何东西 *>:直到你找到> //g:将任何这样的字符串替换为空。


齿顶高

我试图清理url,但我遇到了困难匹配/排除一个词- href -使用上面的方法。我简要地研究了反向查找(正则表达式来匹配不包含单词的行),但这种方法似乎过于复杂,并没有提供令人满意的解决方案。

我决定用'(反标记)替换href,做正则表达式替换,然后用href替换'。

示例(为便于阅读,此处格式化):

printf '\n
<a aaa h href="apple">apple</a>
<a bbb "c=ccc" href="banana">banana</a>
<a class="gtm-content-click"
   data-vars-link-text="nope"
   data-vars-click-url="https://blablabla"
   data-vars-event-category="story"
   data-vars-sub-category="story"
   data-vars-item="in_content_link"
   data-vars-link-text
   href="https:example.com">Example.com</a>\n\n' |
sed 's/href/`/g ;
     s/<a[^`]*`/\n<a href/g'

<a href="apple">apple</a> 
<a href="banana">banana</a> 
<a href="https:example.com">Example.com</a>

解释:基本如上。在这里,

S /href/ ':将href替换为'(反引号) s/<a:查找URL开头 [^ ']:后面跟着任何不是'(反撇号) * ':直到你找到一个' /<a href/g:用<a href替换每一个找到的

其他回答

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

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://).它只打印匹配的部分。

还没有看到这个答案,所以这里是如何用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正则表达式了。

Sed当然有它的位置,但这不是其中之一!

正如迪伊所指出的:用切就可以了。在这种情况下,它要简单得多,也安全得多。下面是一个使用Bash语法从URL中提取各种组件的示例:

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

protocol=$(echo "$url" | cut -d':' -f1)
host=$(echo "$url" | cut -d'/' -f3)
urlhost=$(echo "$url" | cut -d'/' -f1-3)
urlpath=$(echo "$url" | cut -d'/' -f4-)

给你:

protocol = "http"
host = "www.suepearson.co.uk"
urlhost = "http://www.suepearson.co.uk"
urlpath = "product/174/71/3816/"

正如你所看到的,这是一个更加灵活的方法。

(全部归功于Dee)