【问题标题】:Replace only if string exists in current line仅当当前行中存在字符串时才替换
【发布时间】:2012-08-11 02:28:10
【问题描述】:

我有这样一行:

sed -i 's/mystring/newstring/' $target

此命令会将所有mystring 更改为newstring

我现在想要的是:当程序看到mystring 时,如果字符串searchstring 存在与否,我如何检查当前行?如果存在,则newstring1;否则,newstring0

【问题讨论】:

  • 你到底想在这里做什么?请描述您要解决的问题,而不是您认为 sed 应该如何解决的问题。
  • 其实我的意思是,我有 2 种模式。对于我找到的所有模式A。我会检查这一行中是否存在patternB。

标签: linux shell sed


【解决方案1】:

这是来自sed one-liners 页面:

优化速度:如果需要提高执行速度(由于 大输入文件或慢速处理器或硬盘),替换将 如果之前指定了“find”表达式,则执行得更快 给出“s/.../.../”指令。因此:

sed 's/foo/bar/g' filename         # standard replace command
sed '/foo/ s/foo/bar/g' filename   # executes more quickly
sed '/foo/ s//bar/g' filename      # shorthand sed syntax

速度不是手头问题的问题,但语法提示有助于制定解决方案:

sed -i '/searchstring/ s/mystring/1/; s/mystring/0/' $target

【讨论】:

    【解决方案2】:

    解决方案

    假设您的输入文件 $target 包含以下内容:

    some text mystring some other text
    some text mystring a searchstring
    just some more text
    

    这个命令:

    sed -i -e '/searchstring/ s/mystring/1/ ; /searchstring/! s/mystring/0/' $target
    

    将其内容更改为:

    some text 0 some other text
    some text 1 a searchstring
    just some more text
    

    说明

    脚本包含两个用分号分隔的替代 (s) 命令。

    substitute 命令接受一个可选的地址范围,用于选择应该替换哪些行。

    在这种情况下,regexp 地址用于选择包含 searchstring 的行以用于第一个命令;以及第二个不包含 searchstring 的行(注意正则表达式否定匹配后的感叹号)。

    编辑

    此命令将执行得更好,并产生相同的结果:

    sed -i -e '/searchstring/ s/mystring/1/ ; s/mystring/0/' $target
    

    关键是命令是按顺序执行的,因此如果当前行之后中还有一个mystring子字符串,那么第一个命令完成后就没有肯定会在里面搜索字符串

    向 user946850 致敬。

    【讨论】:

    • 你只是快了一点 :-)
    • @user946850 虽然您的版本执行得更快。偷了它:D
    • 只是一个小问题:shebang 看起来像 #!,我在您的代码中没有看到......
    • 不必使用-e 选项(请参阅this 答案)。
    猜你喜欢
    • 1970-01-01
    • 2021-06-02
    • 2017-07-13
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 2017-01-05
    相关资源
    最近更新 更多