sed 替换不以 http:// 开头的部分行

Joh*_*unt 3 sed regular-expression

我被 sed 卡住了 .. 我试图在 html 文件中的链接不以 http 开头时使用 / 前缀。我知道这可能不是解决此问题的最佳方法,但我只是在一个简单的快速/解决方案之后。

到目前为止,我已经尝试过这个(注意 IRL 我将使用 -i in place 标志等,这仅用于测试):

echo '<a href="egww">blah</a><a href="http://bloge.weg">yeah</a>' |
sed 's@href="[^http]@href="/@g'
Run Code Online (Sandbox Code Playgroud)

这几乎有效:

<a href="/gww">blah</a><a href="http://bloge.weg">yeah</a>
Run Code Online (Sandbox Code Playgroud)

除了第一个链接的第一个字符被切断外,我认为它与 h、t、t 或 p 不匹配,而不是整个字符串 http:

echo '<a href="egww">blah</a><a href="p/bloge.weg">damn</a>' |
sed 's@href="[^http]@href="/@g'

<a href="/gww">blah</a><a href="p/bloge.weg">damn</a>
Run Code Online (Sandbox Code Playgroud)

在这一点上我很困惑,不幸的是谷歌在这里没有多大帮助,因为 sed 的否定通常用于删除包含字符串的行而不是不匹配行中的子字符串..我尝试了几个“正常”正则表达式模式,但这些似乎不起作用。

有任何想法吗?

Sté*_*las 5

[^http]不是什么,而是http。该 RE 匹配一个字符,只要它既不是h,也不是,也不t是p。所以href="[^http]匹配href="bin href="blah",但不匹配href="tin href="toto"。

在这里,你会想要这样的东西:

sed -E 's@(href=")([^h]|h([^t]|t([^t]|t([^p]|$)|$)|$)|$)@\1/\2@g'
Run Code Online (Sandbox Code Playgroud)

也就是说href=",随后要么不可─ h(一个比其他字符h),或h-not- t,或ht-not- t,或htt-not- p,或htt-EOL,或ht-EOL或h-EOL或EOL。(EOL ==“行尾”,最后 4 个不太可能在输入中找到,因为这意味着"不匹配)。

(假设您sed支持尚未标准的-E选项)。

您还可以添加/always 但在 when in 之后将其删除href="/http:

sed 's@href="@&/@g;s@href="/http@href="http@g'
Run Code Online (Sandbox Code Playgroud)

或与perl:

perl -pe 's|href="\K(?!http)|/|g'
Run Code Online (Sandbox Code Playgroud)

Usingperl的否定前瞻 RE 运算符。