How to use sed to replace only the first occurrence in a file?

前端 未结 23 785
别跟我提以往
别跟我提以往 2020-11-22 04:27

I would like to update a large number of C++ source files with an extra include directive before any existing #includes. For this sort of task, I normally use a small bash s

相关标签:
23条回答
  • 2020-11-22 04:51
    sed -e 's/pattern/REPLACEMENT/1' <INPUTFILE
    
    0 讨论(0)
  • 2020-11-22 04:54
    #!/bin/sed -f
    1,/^#include/ {
        /^#include/i\
    #include "newfile.h"
    }
    

    How this script works: For lines between 1 and the first #include (after line 1), if the line starts with #include, then prepend the specified line.

    However, if the first #include is in line 1, then both line 1 and the next subsequent #include will have the line prepended. If you are using GNU sed, it has an extension where 0,/^#include/ (instead of 1,) will do the right thing.

    0 讨论(0)
  • 2020-11-22 04:54

    Just add the number of occurrence at the end:

    sed s/#include/#include "newfile.h"\n#include/1
    
    0 讨论(0)
  • 2020-11-22 04:54

    This might work for you (GNU sed):

    sed -si '/#include/{s//& "newfile.h\n&/;:a;$!{n;ba}}' file1 file2 file....
    

    or if memory is not a problem:

    sed -si ':a;$!{N;ba};s/#include/& "newfile.h\n&/' file1 file2 file...
    
    0 讨论(0)
  • 2020-11-22 04:58

    POSIXly (also valid in sed), Only one regex used, need memory only for one line (as usual):

    sed '/\(#include\).*/!b;//{h;s//\1 "newfile.h"/;G};:1;n;b1'
    

    Explained:

    sed '
    /\(#include\).*/!b          # Only one regex used. On lines not matching
                                # the text  `#include` **yet**,
                                # branch to end, cause the default print. Re-start.
    //{                         # On first line matching previous regex.
        h                       # hold the line.
        s//\1 "newfile.h"/      # append ` "newfile.h"` to the `#include` matched.
        G                       # append a newline.
      }                         # end of replacement.
    :1                          # Once **one** replacement got done (the first match)
    n                           # Loop continually reading a line each time
    b1                          # and printing it by default.
    '                           # end of sed script.
    
    0 讨论(0)
提交回复
热议问题