Rich Williams
Rich Williams

Reputation: 49

Shell script for string replacement of HTML file

I'm trying to take an HTML template and replace a few placeholders with a custom string.

I'm doing a curl of a template on github: str=$(curl https://raw.github.com/toneworm/template-html5-sass/master/index.html) saving the following to a variable:-

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="description" content="[name]">
<meta name="author" content="">
<title>[name]</title>
<link type="text/css" rel="stylesheet" href="css/styles.css" />
<!--[if lt IE 9]>
    <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<!-- scripts -->
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>

I want to do a global replace [name] with something else (TEST in this example)...

Currently I have sed -i 's/\[name\]/TEST/g' $first > index.html which throws the following error:-

sed: 1: "<!DOCTYPE": invalid command code <

Any ideas?

Upvotes: 1

Views: 2777

Answers (4)

Gordon Davisson
Gordon Davisson

Reputation: 125918

Several others have given alternatives that solve the problem; let me explain why the original doesn't work. There are actually three problems:

  1. sed's -i flag takes an argument (optional in the GNU version of sed, required in the BSD version OS X uses). So s/\[name\]/TEST/g gets interpreted as an argument to -i instead of an edit operation. BTW, -i means operate on an existing file in-place, but since you aren't operating on a file this is unwanted anyway.

  2. After the edit to perform, sed's next argument should be a filename to operate on, not a string to operate on. You either need to save it to a file, or echo it and pipe that into sed.

  3. Since $first is not in double-quotes, the shell performs word splitting (and some other things) on it after expansion. This means that "<!DOCTYPE", "html>", "<html" etc are each passed to sed as separate arguments. Since s/\[name\]/TEST/g got interpreted as an argument to -i, the first one ("<!DOCTYPE") gets treated as an edit command (which is invalid), and the rest as filenames (which it never gets around to trying to open).

Upvotes: 0

Digital Trauma
Digital Trauma

Reputation: 16016

echo "$first" | sed -e 's/\[name\]/TEST/g' > index.html

Upvotes: 0

V H
V H

Reputation: 8587

for multiple search replace check out this link

You can also use Perl which simplifies by not requiring you to backslash content:

#RAND=$$;
in1="$1"
out1="$2";
#cp $3 /tmp/$3.$RAND
in=$in1 out=$out1 perl -pi -e 's/\Q$ENV{"in"}/$ENV{"out"}/g' $3 

and here is an alternative way of using 1 file:

url=https://raw.github.com/toneworm/template-html5-sass/master/index.html; curl $url |sed "s:\[name\]:TEST:g" > index1.html

Upvotes: 1

iamauser
iamauser

Reputation: 11479

Why are you saving the output of the curl command to a string variable ? You could save the file to a different name and then use that file for the sed.

curl https://raw.github.com/toneworm/template-html5-sass/master/index.html test.html
sed "s|\[name\]|TEST|g" test.html > index.html

Upvotes: 0

Related Questions