如何高效合并sed命令:将hits字段0替换为false、非零替换为true
问题描述
需要处理文件中的hits字段:将值为0的替换为false,所有非零值替换为true。目前使用多条sed命令逐值替换:
sed -i '/<line/s/hits="0"/hits="false"/g' $coverage_file sed -i '/<line/s/hits="1"/hits="true"/g' $coverage_file sed -i '/<line/s/hits="2"/hits="true"/g' $coverage_file sed -i '/<line/s/hits="3"/hits="true"/g' $coverage_file
输入样例文本:
branch="false" hits="0" lineNumber="36" branch="false" hits="1" lineNumber="36" branch="false" hits="2" lineNumber="36" branch="false" hits="211" lineNumber="36" branch="false" hits="411" lineNumber="36"
期望输出:
branch="false" hits="false" lineNumber="36" branch="false" hits="true" lineNumber="36" branch="false" hits="true" lineNumber="36" branch="false" hits="true" lineNumber="36" branch="false" hits="true" lineNumber="36"
请问能否将这些操作合并为更少的命令?
优化方案
完全可以,用一条sed命令就能搞定所有替换,这里提供两种实用写法:
写法一:多替换规则串联
sed -i '/<line/s/hits="0"/hits="false"/g; /<line/s/hits="[^0][0-9]*"/hits="true"/g' $coverage_file
逻辑很直接:
- 先对包含
<line>的行,把hits="0"替换为hits="false" - 再对包含
<line>的行,匹配hits="后接非0开头的数字串(覆盖所有非零的单/多位数),替换为hits="true"
写法二:利用sed分支跳转(GNU sed支持)
sed -i '/<line/{s/hits="0"/hits="false"/; t; s/hits="[0-9]*"/hits="true"/}' $coverage_file
这个写法更高效:
- 先定位到包含
<line>的行 - 尝试替换
hits="0",如果替换成功(t命令会跳转到脚本末尾),就跳过后面的操作 - 如果替换失败(说明不是0),就把所有数字值的
hits替换为true
两种写法都能一次性处理所有情况,不用再写多条重复命令。
内容的提问来源于stack exchange,提问作者AhmFM
相关产品推荐
相关产品推荐

