first replacement of a string in a file using sed first replacement of a string in a file using sed unix unix

first replacement of a string in a file using sed


There’s certainly no need to write some big long script when it only takes on substitution to do all the work in one line. You just have to pick the right Power Tool for the job.

Here’s a Perl one-liner:

% cat -n /tmp/f     1  import java.lang.Character;     2  import java.io.File;     3  import java.io.File;     4  import java.util.Pattern;% perl -pe 's//IoException/ if m?import java\.io\.\KFile?' /tmp/fimport java.lang.Character;import java.io.IoException;import java.io.File;import java.util.Pattern;

And if you want to do it with an edit of the file, just add -i.bak:

% perl -i.bak -pe 's//IoException/ if m?import java\.io\.\KFile?' /tmp/f% head /tmp/f{,.bak}==> /tmp/f <==import java.lang.Character;import java.io.IoException;import java.io.File;import java.util.Pattern;==> /tmp/f.bak <==import java.lang.Character;import java.io.File;import java.io.File;import java.util.Pattern;

The reason that works is because when you give the m// operator a ?? delimiter, it has some built-in state to remember to match the first time only.

Then in the substitute, the empty pattern means to reuse the last matched pattern, so you don’t have to type it again and risk the two ever divering.

Finally, the \K in the pattern reneges on the match, “keeping” the stuff to the left, so that it doesn’t get gobbled by the substitute.


cat file | sed -e ':l    0,/my_search_str/ {    /my_search_str/! {            N;            b l            }    s/my_search_str/replace_this/g      :t    N    b t         }    '

this is working for me:file: (before)

hello1my_search_strhello2mysearch_strhello3

file:(after)

hello1replace_thishello2mysearch_strhello3


What I would do is to append all the lines in a great line and replace the content.

$ cat fimport java.io.File;import java.io.File;$ sed -n 'N  ${    s/import java.io.File;/import java.io.IOException/    p  }' fimport java.io.IOExceptionimport java.io.File;

How it works: first, I suppress the line printing, which is the default behavior, passing the -n option to sed.

Then there comes the sed commmands. The first one is the N command: it appends a newline and the next line of the stream to the current one, maintaining then at the pattern space. This will change the current line to the next one, and then the next line will be appended... until the end of the file.

At the end of the file and after the N command to be executed at the last line as well, the pattern space will contain all the lines. Then, at the end of the file (which is specified by the $ address) we just replace the desired line with:

s/import java.io.File;/import java.io.IOException/

Since the s/// command does only one replacement per iteration at the pattern space by default, it will only replace the first line. Now the pattern space has the line replaced, but will not be printed out since we used the -n option. So, we need to print it with the p command. Once we will execute two operations at the end of the file, we adress it with $ and put the operations between brackets ({}).

There, we just presented the sed commands in more than one line for clarity. We can use them all in one line; just separate them by semicolons:

$ sed -n 'N;${s/import java.io.File;/import java.io.IOException/;p;}' fimport java.io.IOExceptionimport java.io.File;

HTH