【问题标题】:Add a # to every line in a file with certain string with sed使用 sed 将 # 添加到具有特定字符串的文件中的每一行
【发布时间】:2013-11-27 13:57:18
【问题描述】:

我有一个像这样的文件(只是其中的一部分)

    center      cont      flux       eqw      core     gfwhm      fwhm                                                
  7367.332 0.3494628 -0.002165  0.006196 -0.026459   0.07688        0.                                                
  7372.827 0.3524984 -9.457E-4  0.002683 -0.011192   0.07938        0.                                                
  7384.392 0.3463771 -0.001513  0.004369 -0.024297   0.05851        0.                                                
  7384.655 0.3457934 -0.003066  0.008867 -0.037102   0.07763        0.                                                
  7387.274  0.347539 -0.014332   0.04124 -0.136604   0.09856        0.                                                
    center      cont      flux       eqw      core     gfwhm     lfwhm                                                
  7391.392 0.3548613 -0.044781    0.1262 -0.203154    0.2071        0.                                                
  7391.645 0.3539104 -0.008767   0.02477 -0.021864    0.3767        0.                                                
    center      cont      flux       eqw      core     gfwhm     lfwhm                                                
  7400.522 0.3491196 -4.204E-4  0.001204 -0.005909   0.06684        0.                                                
  7405.889  0.348969 -6.845E-4  0.001961 -0.009793   0.06566        0.

我想在每行的开头添加一个#,其中包含centercont 等字符串。它们看起来都很相似,所以搜索center 就足够了。

如果另外我可以添加到脚本中,那将不会发生任何事情,如果它们的行已经包含一个 # 这会很棒,但在这里不是超级重要。

输出应如下所示:

   #center      cont      flux       eqw      core     gfwhm      fwhm                                                
  7367.332 0.3494628 -0.002165  0.006196 -0.026459   0.07688        0.                                                
  7372.827 0.3524984 -9.457E-4  0.002683 -0.011192   0.07938        0.                                                
  7384.392 0.3463771 -0.001513  0.004369 -0.024297   0.05851        0.                                                
  7384.655 0.3457934 -0.003066  0.008867 -0.037102   0.07763        0.                                                
  7387.274  0.347539 -0.014332   0.04124 -0.136604   0.09856        0.                                                
   #center      cont      flux       eqw      core     gfwhm     lfwhm                                                
  7391.392 0.3548613 -0.044781    0.1262 -0.203154    0.2071        0.                                                
  7391.645 0.3539104 -0.008767   0.02477 -0.021864    0.3767        0.                                                
   #center      cont      flux       eqw      core     gfwhm     lfwhm                                                
  7400.522 0.3491196 -4.204E-4  0.001204 -0.005909   0.06684        0.                                                
  7405.889  0.348969 -6.845E-4  0.001961 -0.009793   0.06566        0.

我认为sed 可以解决这个问题,但如果有人有更好的想法,我想在这里。

【问题讨论】:

    标签: bash search replace sed


    【解决方案1】:

    使用sed,你可以说:

    sed -r 's/^(\s+)(center)/\1#\2/g' filename
    

    这将导致:

        #center      cont      flux       eqw      core     gfwhm      fwhm          
      7367.332 0.3494628 -0.002165  0.006196 -0.026459   0.07688        0.           
      7372.827 0.3524984 -9.457E-4  0.002683 -0.011192   0.07938        0.           
      7384.392 0.3463771 -0.001513  0.004369 -0.024297   0.05851        0.           
      7384.655 0.3457934 -0.003066  0.008867 -0.037102   0.07763        0.           
      7387.274  0.347539 -0.014332   0.04124 -0.136604   0.09856        0.           
        #center      cont      flux       eqw      core     gfwhm     lfwhm          
      7391.392 0.3548613 -0.044781    0.1262 -0.203154    0.2071        0.           
      7391.645 0.3539104 -0.008767   0.02477 -0.021864    0.3767        0.           
        #center      cont      flux       eqw      core     gfwhm     lfwhm          
      7400.522 0.3491196 -4.204E-4  0.001204 -0.005909   0.06684        0.           
      7405.889  0.348969 -6.845E-4  0.001961 -0.009793   0.06566        0.
    

    【讨论】:

      【解决方案2】:

      使用sed,您可以使用/center/ 过滤带有center 的行,然后用# 替换行的开头(^):

      $ sed '/center/s/^/#/' file
      #    center      cont      flux       eqw      core     gfwhm      fwhm
        7367.332 0.3494628 -0.002165  0.006196 -0.026459   0.07688        0.
        7372.827 0.3524984 -9.457E-4  0.002683 -0.011192   0.07938        0.
        7384.392 0.3463771 -0.001513  0.004369 -0.024297   0.05851        0.
        7384.655 0.3457934 -0.003066  0.008867 -0.037102   0.07763        0.
        7387.274  0.347539 -0.014332   0.04124 -0.136604   0.09856        0.
      #    center      cont      flux       eqw      core     gfwhm     lfwhm
        7391.392 0.3548613 -0.044781    0.1262 -0.203154    0.2071        0.
        7391.645 0.3539104 -0.008767   0.02477 -0.021864    0.3767        0.
      #    center      cont      flux       eqw      core     gfwhm     lfwhm
        7400.522 0.3491196 -4.204E-4  0.001204 -0.005909   0.06684        0.
        7405.889  0.348969 -6.845E-4  0.001961 -0.009793   0.06566        0.
      

      如果您需要 # 正好在 center 文本旁边,那么这样做:抓住空格,然后在 # 之前将它们打印回来。

      $ sed -r '/center/s/^(\s*)/\1#/' file
          #center      cont      flux       eqw      core     gfwhm      fwhm
        7367.332 0.3494628 -0.002165  0.006196 -0.026459   0.07688        0.
      ...
      

      如果您的sed 中没有-r 选项,您可以使用等效项:

      sed '/center/s/^\(\s*\)/\1#/' file
      

      使用awk 更快:您可以过滤包含center 的行并将# 添加到第一个字段:

      $ awk '/center/ {$1="#"$1}1' file
      #center cont flux eqw core gfwhm fwhm
        7367.332 0.3494628 -0.002165  0.006196 -0.026459   0.07688        0.
        7372.827 0.3524984 -9.457E-4  0.002683 -0.011192   0.07938        0.
      ...
      

      【讨论】:

      • 速度在这里不是问题,但感谢非常好的示例和解释。它工作得很好,但就目前而言,cforbish 的方法是最好的。
      • 没问题 :) 我看不出两者有什么不同,除了他使用-i 就地版本。
      • 在这种情况下不需要最后一个“g”(仅替换 1 个)
      • 你是对的,@NeronLeVelu,已相应更新。谢谢!
      【解决方案3】:

      使用 sed 很简单:

       sed -i.bak '/center/s/^\([^#]\)/#\1/' file.txt
      

      发生了什么(来自tutorialspoint.comman sedsed regex):

      -i.bak     Edit files in place (makes backup if extension supplied)
      /center/   Matches lines that contain the word center.
      s/???/???/ Or s/regexp/replacement/, Attempt to match regexp against the pattern space.
      /          Field separator to 's'.
      ^          Match first character on line.
      \(         Start back reference.
      [^#]       Do not match any charcter (^ = don't) in this list (only # listed).
      \)         End back reference.
      #          Literal '#'
      \1         The first back reference.
      

      同样的事情只是不产生备份文件(file.txt.bak):

       sed -i '/center/s/^\([^#]\)/#\1/' file.txt
      

      【讨论】:

        【解决方案4】:

        使用awk

        awk '{sub(/center/,"#&")}1' file
        

        【讨论】:

          【解决方案5】:
          sed "/center/ !b;s/^\s*/&#/"
          

          在这种情况下我们也可以尝试

          sed "/[0-9]/ b;s/^\s*/&#/"
          

          假设文本行中没有数字或

          sed "/[a-zA-Z]/ s/^\s*/&#/"
          

          假设数据行中没有字母

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-11-04
            • 1970-01-01
            • 1970-01-01
            • 2020-12-21
            • 2020-04-03
            • 1970-01-01
            • 2018-07-28
            相关资源
            最近更新 更多