sed 用多次出现的单词替换单词分隔符

Posted

技术标签:

【中文标题】sed 用多次出现的单词替换单词分隔符【英文标题】:sed replace word delimiter with multiple occurences of word 【发布时间】:2014-09-27 10:08:56 【问题描述】:

sed 有点新。我制作了一个脚本来替换文件中的各种文本。例如,文件test.txt 包含:

My name is <Jack>.
My dad calls me <Jack>. My mum calls me <Jack>, too.

我想将“”替换为“:”。我用了这个命令

sed -re 's/<(.+?)>/:\1:/g' test.txt

返回

My name is :Jack:.
My dad calls me :Jack>. My mum calls me <Jack:, too.

因此,它适用于一行中的一次出现。结果在一行中多次出现是错误的,因为 sed 参数是第一个“”之间的所有文本。

有什么提示吗? (还有一点解释……)

谢谢!

编辑:

使用 Gedit 或其他编辑器中的替换,相同的正则表达式可以正常工作。

【问题讨论】:

【参考方案1】:

最简单:

kent$  echo "My name is <Jack>.
dquote> My dad calls me <Jack>. My mum calls me <Jack>, too."|sed 's/[<>]/:/g'
My name is :Jack:.
My dad calls me :Jack:. My mum calls me :Jack:, too.

如果你想使用组:

kent$  echo "My name is <Jack>.
My dad calls me <Jack>. My mum calls me <Jack>, too."|sed -r 's/<([^>]*)>/:\1:/g'
My name is :Jack:.
My dad calls me :Jack:. My mum calls me :Jack:, too.

在您的代码中,您想使用非贪婪匹配,不幸的是,sed 不支持。所以你得到输出的原因是:

整体

<Jack>. My mum calls me <Jack>

就像&lt;....&gt;

.+ 匹配 Jack&gt;. My mum calls me &lt;Jack

【讨论】:

或者,s/&lt;[^&gt;]+&gt;/:\1:/g 感谢“sed 不支持非贪婪匹配”信息。这就解释了为什么我可以在 Gedit 中使用相同的正则表达式并且它有效(编辑了我的问题)。我将分析您的代码并进行测试。不能直接使用它,因为实际替换比替换“”要复杂一些;这是一个简短的例子。好吧,既然我在这里问...如果“杰克”被一个 html 标签包围怎么办(例如 Jack)【参考方案2】:

我更新了示例。

这里是 test.html:

My name is <a href="filename.html#firstAnchor">Jack</a>.
My dad calls me <a href="filename.html#firstAnchor">Jack</a>. My mum calls me <a href="filename.html#secondAnchor">Jack</a>, too.

这个命令给了我预期的结果:

sed -re 's/<a href="filename.html#[^>]*>([^<]*)<\/a>/:\1:/g' test.html

结果:

My name is :Jack:.
My dad calls me :Jack:. My mum calls me :Jack:, too.

sed 搜索以&lt;a href="filename.html# 开头的标签和所有后续字符但不是 ">"(选项[^&gt;]),而不是搜索直到">"。参数是任何字符“[^<]),而不是分隔符是“”。

我收到了吗?

【讨论】:

以上是关于sed 用多次出现的单词替换单词分隔符的主要内容,如果未能解决你的问题,请参考以下文章

搜索和替换不仅可以用空格分隔的整个单词

统计一段文章的单词频率,取出频率最高的5个单词和个数(python)

C# 正则表达式匹配具有分隔符的字符串

用文件中的另一个词替换特定词[关闭]

使用sed用多行替换一个单词?

C语言,输入一行英文字母,统计其中有多少个单词,单词之间用空格分隔.