Home > Back-end >  Bash sed replace until end of line
Bash sed replace until end of line

Time:06-02

I have the following input file:

this is text
     identifier {
         item /directory/file_1234 
some more text 
item /directory/file_1234 other line text
     identifier {
         item /directory/98_76file
other line

I want to replace the stings item /directory/*, that come after the line identifier { with /directory/file_ABC

I tried

cat input | sed ':a;N;$!ba;s/    identifier {\n        item \/directory\/.*$/    identifier {\n        newitem \/directory2\/file_ABC/g'

but it erases the lines after the first occurrence

this is text
    identifier {
        newitem /directory2/file_ABC

CodePudding user response:

Assuming you want to replace both occurances, you can use this sed

$ sed '/identifier {/{N;s~\(.*\n[^[:alpha:]]*\).*~\1newitem /directory/file_ABC~}' input_file
this is text
     identifier {
         newitem /directory/file_ABC
some more text
item /directory/file_1234 other line text
     identifier {
         newitem /directory/file_ABC
other line

CodePudding user response:

Your problem comes form the final .*$ of your pattern: in multi-line mode it matches until the end of the pattern space. Try (tested with GNU sed):

$ sed -E ':a;N;$!ba;s!((^|\n)  identifier \{\n  )item /directory/[^\n]*!\1newitem /directory2/file_ABC!g' input
this is text
     identifier {
         newitem /directory2/file_ABC
some more text 
item /directory/file_1234 other line text
     identifier {
         newitem /directory2/file_ABC
other line

Note: using cat to feed sed is an anti-pattern. Simply sed 'script' file.

Note: using ! as fields separator of the substitute command instead of / avoids escapes and using the -E option simplifies a bit more.

  • Related