0

I have a number of HTML files that have the same section I want replaced:

  <div id="main-content" class="span12">
    <h1 id="404-page-not-found" style="text-align: center">404</h1>
    <p style="text-align: center"><strong>Page not found</strong></p>
    <p style="text-align: center"><a href=".">Home</a></p>
  </div>

I want to replace this code with {{NAV}}

I feel like I can do something like:

bash script:

#!/bin/bash
find -name '*.html' | while read FILE; do
    sed --in-place -f replace.sed "$FILE"
done

replace.sed:

<my code above here>{
    r replacement
    d
}

replacement:

{{NAV}}

But I cannot get the code I want gone and replaced correct in replace.sed.

Can anyone think of a better way or how to format my code properly?

2
  • 2
    multi line replacement is not trivial with sed, you either replace newlines with some other delimiter to replace at once, or write a sed program to match line by line. If you text is well formatted, awk might be a better option. Commented Jan 11, 2016 at 22:22
  • @karakfa the text is the same, exactly in every file. Commented Jan 11, 2016 at 22:23

1 Answer 1

1

If you replace your replace.sed with this, it should work:

/<div id="main-content" class="span12">/ {  # If we match the first line
    :x               # Label to branch to
    N                # Read next line into pattern buffer
    /<\/div>$/! bx   # If we don't match the closing tag, branch to x
    c \{{NAV}}       # Replace the pattern buffer with {{NAV}}
}

This works if the first and last line are enough to uniquely identify the piece of html to replace. If you want to exactly match the whole snippet, you could do it like this:

/^<div id="main-content" class="span12">/ {
    N
    /<h1 id="404-page-not-found" style="text-align: center">404<\/h1>/! b
    N
    /<p style="text-align: center"><strong>Page not found<\/strong><\/p>/! b
    N
    /<p style="text-align: center"><a href=".">Home<\/a><\/p>/! b
    N
    /<\/div>$/ c \{{NAV}}
}

This one works as follows:

  • If the first line is matched, load the next line (N)
  • If the pattern space now doesn't match the second line, branch to the end of the cycle (b) and print the pattern space, else load the next line
  • Repeat for lines three and four
  • If now the closing tag is at the end of the pattern space, replace the whole pattern space with {{NAV}}, else just print it
Sign up to request clarification or add additional context in comments.

8 Comments

I am trying the first one and getting: $ /usr/local/Library/ENV/4.3/sed -i .bak -f replace.sed 404.html sed: 3: replace.sed: extra characters at the end of N command
@Jason Which version of sed are you using? Some flavours don't play well with comments.
I am using whatever is part of OS X 10.11. I'm sorry man sed doesn't seem to have a version flag so I can double check. I can try to remove the comments too
FYI, the second one gives me a similar error but with h and not N
@Jason sed --version usually shows the version. And there is no h in the second one...?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.