dannyyy
dannyyy

Reputation: 1784

Replace token in a file with any content

As a final result I want to copy several lines of text from file input.html to output.html.

input.html

 <body>
   <h1>Input File</h1>
   <!-- START:TEMPLATES -->
   <div>
      <p>Lorem Ipsum &amp; Lorem Ipsum</p>
      <span>Path: /home/users/abc.txt</span>
   </div>
   <!-- END:TEMPLATES -->
 <body>

template.html

 <body>
   <h1>Template File</h1>
   <!-- INSERT:TEMPLATES -->
   <p>This is a Text with &nbsp; &amp; /</p>
 <body>

I tried different things in Powershell and Bash to get this work done. But not with success.

Getting the input into a variable is successfuly done by:

content="$(sed -e '/BEGIN:TEMPLATES/,/END:TEMPLATES/!d' input.html)"`

But to replace in another file is impossible. I tried sed and awk. Both habe a lot of problems if the variable contains any special character like & /, ...

output.html

 <body>
   <h1>Output File</h1>
   <div>
      <p>Lorem Ipsum &amp; Lorem Ipsum</p>
      <span>Path: /home/users/abc.txt</span>
   </div>
   <p>This is a Text with &nbsp; &amp; /</p>
 <body>

Thank you for any inputs that helps solving my problem.

Upvotes: 0

Views: 660

Answers (2)

lw0v0wl
lw0v0wl

Reputation: 674

Solution with awk.

get all line from file input.html between <!-- START:TEMPLATES --> and <!-- END:TEMPLATES --> stored it in an array insert_var.

In END section get template.html printed line by line in while loop. If line contain <!-- INSERT:TEMPLATES --> then print contents of array insert_var.

The output get redirected to output.html

As far as I know awk not messing with those special characters.

awk -v temp_file="template.html" '

BEGIN{input_line_num=1} 

/<!-- END:TEMPLATES -->/{linestart=0}
{ if(( linestart >= 1)) {insert_var[input_line_num]=$0; input_line_num++}}
/<!-- START:TEMPLATES -->/{linestart=1} 

END{ while ((getline<temp_file) > 0) 
    {if (( $0 ~ "<!-- INSERT:TEMPLATES -->")) 
        {for ( i = 1;i < input_line_num; i++) {print insert_var[i]}} 
    else { print } }}
' input.html > output.html

Upvotes: 1

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174690

If the START/END comments are on separate lines I'd build a simple parser for the input file like this:

$inTemplate = $false
$template = switch -Wildcard -File '.\input.html' {
  '*<!-- START:TEMPLATES -->*'{
    $inTemplate = $true
  }
  '*<!-- END:TEMPLATES -->*'{
    $inTemplate = $false
  }
  default{
    if($inTemplate){
      $_
    }
  }
}

Now we can do the same thing for the template file:

$output = switch -Wildcard -File '.\template.html' {
  '*<!-- INSERT:TEMPLATES -->*'{
    # return our template input
    $template
  }
  default{
    # otherwise return the input string as is
    $_
  }
}

# output to file
$output |Set-Content output.html

Upvotes: 1

Related Questions