8

I am currently trying to automate updating the text of a file, titled original_file.txt. Imagine the file looks like the following:

common_text
### REPLACE EVERYTHING AFTER THIS LINE ###
text_that_will
be_removed
after_the_command

This file will be updated by removing all text after "Replace everything after this line", and replacing it with the text in the file replacement_file.txt. For the sake of the post, imagine that replacement_file.txt has the following text:

testing123
this_is_the_replacement_text

From what I've been able to find with sed, I can only figure out how to edit the rest of the line after a certain phrase. I want to replace the text in original_file.txt after the replacement phrase with all of the text from replacement_file.txt (I want to keep the replace line text for future updates). original_file.txt should look like this at the end:

common_text
### REPLACE EVERYTHING AFTER THIS LINE ###
testing123
this_is_the_replacement_text

Thanks in advance!

7

Using sed:

sed -n -e '1,/^### REPLACE EVERYTHING AFTER THIS LINE ###$/{ p; d; }' \
       -e 'r replacement_file.txt' \
       -e 'q' original_file.txt

The three sed blocks do this:

  1. The first block prints all lines from line 1 to the line with the special contents. I print these lines explicitly with p and then invoke d to force a new cycle to start ("print; next" in awk).
  2. After the initial lines have been outputted by the first block, the second block outputs the contents of the extra file.
  3. The editing script is then terminated.

Ordinarily, q in the third block would output the current line before quitting (this would be the line in the example data reading text_that_will), but since sed is invoked with -n, this default outputting of a line at the end of a cycle is inhibited.

The result of the above command, given your data, is

common_text
### REPLACE EVERYTHING AFTER THIS LINE ###
testing123
this_is_the_replacement_text

To update the original file, you could use sed -i ..., or redirect the output to a new file that you then replace the original with:

sed ... original_file.txt >original_file.txt.new &&
mv original_file.txt.new original_file.txt
| improve this answer | |
  • Thank you, this worked for me, and I really appreciate the explanation. Quick clarification question: If instead of '### Replace everything after this line ###', I have a javascript comment which instead reads '//Replace below', how might I do that? I am having trouble writing the sed to account for the special characters '//'. Thank you once again. – ddantas Mar 30 at 23:12
15

In GNU/awk:

Name the two files as arguments.

awk '{ print; } /^### REPLACE EVERYTHING AFTER THIS LINE ###$/ { nextfile; }' fn1 fn2
| improve this answer | |
14

Print all lines until "replace after" line is found, then read from other file & quit:

sed '/^### REPLACE EVERYTHING AFTER THIS LINE ###$/{r replacement_file.txt
q;}' original_file.txt

  • use sed -i to save changes
  • or ... > tmp && mv tmp original
| improve this answer | |
  • Neater than mine. Good. Would have been nice with some explanatory text though. – Kusalananda Mar 30 at 7:51
  • 1
    @Kusalananda this one is also rock solid. Yours would fail to work properly if MATCH was on the 1st line (assuming at least two lines of input) for reasons explained here at 1:. – don_crissti Mar 30 at 13:31
6

This will work efficiently using any awk and cat:

$ awk '{print} /### REPLACE EVERYTHING AFTER THIS LINE ###/{exit}' original_file.txt &&
    cat replacement_file.txt
common_text
### REPLACE EVERYTHING AFTER THIS LINE ###
testing123
this_is_the_replacement_text

As with any UNIX tools, to update the original just write the output to a temp file and then replace the original with that temp file:

{ awk '{print} /### REPLACE EVERYTHING AFTER THIS LINE ###/{exit}' original_file.txt &&
   cat replacement_file.txt; } > tmp && mv tmp original_file.txt
| improve this answer | |
3

if using gnu Awk:

awk '{print} /### REPLACE.../{system("cat replacement"); exit 0}' file
| improve this answer | |
3

If you want to edit a file, prefer ed over sed:

ed -s original_file.txt <<'EOF'
/^### REPLACE/+1,$d
r replacement_file.txt
w
EOF

will delete everything after the replace line, insert the contents of the other file, and then save the changes.

| improve this answer | |
0

Tested and worked fine

Command

sed  -ni -e   '1,/#/p' -e '/#/r replacement_file.txt'  titled original_file.txt

output

common_text
### REPLACE EVERYTHING AFTER THIS LINE ###
testing123
this_is_the_replacement_text
| improve this answer | |
  • 1
    It works with OP input sample but doesn't always work: see my comment under rowboat's answer... – don_crissti Mar 30 at 16:28
  • ok will check thanks – Praveen Kumar BS Mar 30 at 16:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.