0

is it possible to use sed to match the source of a script tag within html (which is not valid xml) and replace the whole match with the files' contents?

e.g. say the html contained

<link rel='stylesheet' href="blah.css">
<script src='foo.js'></script>
<script type="text/javascript" src="bar.js"></script>
<title />

I want to not only match 'foo.js' from within src='foo.js' but also to replace in this file the contents of foo.js, so to end up

<link rel='stylesheet' href='blah.css'>
<script>var foo = {};</script>
<script>var bar = [];</script>
<title />  

In a regex I can match the script tag src value like so:

<script\s+(?:[^>]*?\s+)?src=(["'])(.*?)\1

with the match being in the second capture group.

I don't mind rewriting the whole line, but how do I get sed to match on that expression - it doesn't seem to like capture groups or backreferences (at least, the way I'm trying it: I know it does). I get an unhelpful

syntax error near unexpected token `)'

Also how can I capture the file name and then pipe its contents back in as the replacement line?

5
  • What is the full sed command that is giving you the error message? What version of sed are you using? Commented Mar 19, 2019 at 12:11
  • sed on osx (so bsd); trying sed -E 's/<script\s+(?:[^>]*?\s+)?src=(["'])(.*?)\1/whatever/' file.html; trying to escape that single quote with \' or \x27 isn't happening
    – frumbert
    Commented Mar 19, 2019 at 12:41
  • Regardless of sed, you need to replace ' with '\'' when you try to write single quotes in single quoted strings. Commented Mar 19, 2019 at 12:46
  • yes. if i reverse the quoting and escape sed -E "s/<script\s+(?:[^>]*?\s+)?src=(["'])(.*?)\1/whatever/" file.html yields RE error: repetition-operator operand invalid which is normally missing -r but -E should cover that
    – frumbert
    Commented Mar 19, 2019 at 12:58
  • * ["'] supposed to be [\"'] of course, but it still has the error
    – frumbert
    Commented Mar 19, 2019 at 13:04

1 Answer 1

1

I would use instead:

awk '
    match($0, "<script src=." jsfile ".></script>") {
        print "<script>"
        while (getline line < jsfile) print line
        print "</script>"
        next
    }
    {print}
' jsfile=foo.js file.html

which outputs

<link rel='stylesheet' href="blah.css">
<script>
var foo = {};
var bar = [];
</script>
<script type="text/javascript" src="bar.js"></script>
<title />

To save the output back to the original html file:

tmp=$(mktemp)
awk ... > "$tmp" && mv "$tmp" file.html
2
  • great! i've heard of awk for a while but never really used it. this example provides exactly what I need to get started. Cheers!
    – frumbert
    Commented Mar 19, 2019 at 21:14
  • I started off trying to solve it with sed, but I couldn't quite get the output in the right order. Commented Mar 19, 2019 at 21:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .