【问题标题】:sed is ignoring some matchessed 忽略了一些匹配项
【发布时间】:2020-09-16 16:46:14
【问题描述】:

我正在尝试使用反向引用将所有匹配的 http 替换为 https:

示例test3.txt 文件:

http://stronka.wpblog.internal http://stronka.wpblog.internal
abc
jdfgijdf dfijog http://stronka.wpblog.internal dfgtdgrtg http://stronka.wpblog.internal/ sfdgth http://stronka.wpblog.internal/dupa drgfthj
ghj gjerioghj fhjdf http://stronka.wpblog.internal/

当我对 test3.txt 文件运行 sed 时:

~# sed -r 's#http(://.*.wpblog.internal)#https\1#g' test3.txt

https://stronka.wpblog.internal http://stronka.wpblog.internal
abc
jdfgijdf dfijog https://stronka.wpblog.internal dfgtdgrtg https://stronka.wpblog.internal/ sfdgth http://stronka.wpblog.internal/dupa drgfthj
ghj gjerioghj fhjdf https://stronka.wpblog.internal/

第 1 行第二个链接保持不变,第 2 行第三个链接保持不变,我迷路了,我怎么能告诉 sed 替换所有匹配的内容?

【问题讨论】:

  • 使用sed 's#http://#https://#g'
  • 这个怎么样:sed 's/http:\/\//https:\/\//g'
  • 您的.* 正在消耗字符串的整个中间部分;将您的模式更改为:s#http(://.*.wpblog.internal)#\1#,这将是显而易见的。

标签: sed


【解决方案1】:

因为.* 通配符是贪婪的,即它会尽可能多地消耗线路。

到目前为止,最简单的解决方案是根本不使用通配符;然后sed 会根据您提供的简单输入完全符合您的期望。

sed 's#http://#https://#g' test3.txt

(除了标准的 1968 正则表达式之外,此正则表达式中的任何内容都不需要任何东西,因此 -r 选项 - 或其 Linux 等效的 -E - 在这里没有必要或有用。)

如果出于某种原因您需要通配符,请使用与 URL 边界不匹配的通配符。在您的示例数据中,空格似乎分隔了不同的 URL,因此我们可以贪婪地匹配尽可能多的非空格字符:

sed -r 's#http(://[^ ]*\.wpblog\.internal)#https\1#g' test3.txt

(请注意我们如何使用\. 来匹配文字点。)

像 Perl 这样的现代正则表达式方言具有非贪婪的通配符,但即便如此,最好使用真正表示您想要的正则表达式。

【讨论】:

    【解决方案2】:

    试试下面:

    sed -r 's/\bhttp\b/https/g' 
    

    \b 用于围绕“http”设置边界

    【讨论】:

      【解决方案3】:

      根据回复我已经替换了贪婪的通配符.*

      sed -E 's#http(://[a-zA-Z0-9.-]*\.wpblog\.internal)#https\1#g'

      它现在可以正常工作了,谢谢大家!

      【讨论】:

        最近更新 更多