Sed: inserting text before end of section

osxsedtext processing

I need to insert some text into an HTML file before the end of the HEAD section.

I'm trying:

sed -i "s#</head>#<style> @page { prince-shrink-to-fit: auto }
.repository-with-sidebar.with-full-navigation .repository-content 
{width: 950px ! important;} </style>\n</head>#" ${1}"/"${2}"/"${i}.html

I'm getting an error:

sed: 1: command a expects \ followed by text

I just don't see my error. I even tried using single quotes around the style.

The exact text I want to insert before the end of the HEAD section is:

<style>
@page { prince-shrink-to-fit: auto }
.repository-with-sidebar.with-full-navigation .repository-content 
{width: 950px ! important;}
</style>

Edit: Here is the exact command:

sed -i "s#</head>#<style> @page { prince-shrink-to-fit: auto } .repository-with-sidebar.with-full-navigation .repository-content {width: 950px ! important;} </style>\n</head>#" ${1}"/"${2}"/"${i}.html

Edit 2: In an effort to try and make sure I was formatting the command correctly I am trying this too:

strToInsert='<style> @page { prince-shrink-to-fit: auto } .repository-with-sidebar.with-full-navigation .repository-content {width: 950px ! important;} </style>'

sed -i "s#</head>#$strToInsert\n</head>#" ${1}"/"${2}"/"${i}.html

This makes me realize it might be a problem with the text I am inserting.

Best Answer

In-place sed requires making a backup file during the process. The -i option on Apple's sed requires an extension argument (for the backup file it creates) and consumes the next argument. That means you're telling it you want it to make a backup file with the extension "#s</head>#...".

The error means it thinks you're referring to the append command. I'm going to guess that the value of $1 starts with an a. Because -i ate the preceding argument sed thinks that this is the script to run, rather than the path to the file to change, and you get errors accordingly. This is exactly the error you would get with Apple sed and an invalid a command:

$ sed a
sed: 1: "a": command a expects \ followed by text

Provide an extension argument to -i in your sed command:

sed -i.bak "s#</head>#<style> @page { prince-shrink-to-fit: auto } .repository-with-sidebar.with-full-navigation .repository-content {width: 50px ! important;} </style>\n</head>#" "${1}/${2}/${i}.html"

and things will work (although note that \n is not a newline escape). If you use single quotes you can even take the space out of "!important".

The above will work on GNU sed as well, but note that -i is not a POSIX option and is not generally portable.

It is often recommended not to use in-place modification anyway, and to handle working with a copy of the file explicitly yourself. That is up to you, though.


You should quote the variable expansions ${1}, etc. Quoting only the slashes is pointless, because those are always literal.

Related Question