只需使用awk:
$ awk '$1=="leaf"{ sub(/-/,"_",$2) } 1' file
dont-touch-these-hyphens
leaf replace_these-hyphens
它可以让你更精确地控制你所匹配的内容(例如上面的示例是对字符串而不是正则表达式进行匹配,因此即使该字符串包含类似于
.
或
*
的正则表达式元字符,它也能正常工作),以及你所要替换的内容(例如上面的示例仅在
leaf
之后的文本中进行替换,因此即使
leaf
本身包含
-
,它也会继续正常工作):
$ cat file
dont-touch-these-hyphens
leaf-foo.*bar replace-these-hyphens
leaf-foobar dont-replace-these-hyphens
正确输出:
$ awk '$1=="leaf-foo.*bar"{ sub(/-/,"_",$2) } 1' file
dont-touch-these-hyphens
leaf-foo.*bar replace_these-hyphens
leaf-foobar dont-replace-these-hyphens
错误输出:
$ sed '/^leaf-foo.*bar/ s/-/_/' file
dont-touch-these-hyphens
leaf_foo.*bar replace-these-hyphens
leaf_foobar dont-replace-these-hyphens
注意,leaf-foo中的“-”在最后两行(包括不以“leaf-foo.*bar”字符串开头的那一行)中被替换为“_”。
该awk脚本可在任何UNIX框架上使用任何awk而不需修改。
\w
的正则表达式扩展。你需要使用sed -E
或sed -r
。 - steveslivased -i -E 's/leaf (\w+)\-/leaf \1_/g' 文件
- Erik Vesterlund\w
。对于 GNU sed,sed
和sed -E
(或sed -r
)之间唯一的区别是你需要转义的内容不同。详见官方文档。 - Benjamin W.+
。抱歉,我有一把锤子,看起来所有东西都像钉子。解决方案正确,但推理错误。 - stevesliva\ +
具有与扩展正则表达式中的+
相同的效果。 除引号外,它们确实是等价的。BRE中的\(\) \{\} \+ \? \|', ERE中的
() {} +?|'。 - Benjamin W.