【问题标题】:Combine two sed commands in one line在一行中合并两个 sed 命令
【发布时间】:2016-03-02 18:57:54
【问题描述】:

我正在寻找一个in place 命令来更改所有以:.:. 结尾的文件行

来自

chr01   1453173 .   C   T   655.85  PASS    .   GT:AD:DP:PGT:PID    0/1:25,29:54:.:.

chr01   1453173 .   C   T   655.85  PASS    .   GT:AD:DP    0/1:25,29:54

换句话说,我基本上是从任何以:.:. 结尾的行中删除:PGT:PID:.:.

【问题讨论】:

    标签: unix awk sed


    【解决方案1】:

    使用 GNU sed 和 Solaris sed:

    sed '/:\.:\.$/{s///;s/PGT:PID//;}' file
    

    如果您想使用 GNU sed “就地”编辑您的文件,请使用选项 -i

    【讨论】:

      【解决方案2】:

      使用 awk 会是:

      awk 'sub(/:\.:\.$/,""){sub(/:PGT:PID/,"")} 1' file
      chr01   1453173 .   C   T   655.85  PASS    .   GT:AD:DP    0/1:25,29:54
      

      对于使用 gawk 进行就地编辑,您可以添加 -i inplace 选项,而对于任何 awk,您只需添加 > tmp && mv tmp file

      【讨论】:

        【解决方案3】:

        您正在寻找类似的东西:

        sed -i.bak "/^.*:\.:\.$/ {s/:PGT:PID//g; s/:\.:\.//g;}" file 
        
        • 它确实就地替换为文件并创建一个作为 file.bak 的备份
        • /^.*:\.:\.$/ 将 s 命令限制为以 :.:. 结尾的行,. 需要引用,因为它们是正则表达式的特殊字符
        • s sommand 将字符串替换为空字符串

        【讨论】:

        • @EdMorton 感谢您的建议,我改进了答案。
        【解决方案4】:

        作为单行:

        sed -i -e '/:\.:\.$/!n' -e 's///' -e 's/:PGT:PID//g' "$file"
        

        扩展:

        /:\.:\.$/!n     # leave lines untouched unless they end in ":.:."
        s///            # replace the matched ":.:." with nothing
        s/:PGT:PID//g   # replace ":PGT:PID" with nothing, everywhere
        

        我们使用-i 标志来执行就地编辑。我们将每一行作为单独的 -e 表达式传递以实现可移植性:一些 sed 实现允许将多个命令与 ; 连接,但这不是 POSIX 标准所要求的。

        【讨论】:

          猜你喜欢
          • 2011-12-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-12
          • 2018-07-07
          • 2015-01-30
          • 1970-01-01
          • 2011-03-21
          • 1970-01-01
          相关资源
          最近更新 更多