Inserting lines between specific other lines in a file

Hi,

I need to edit ssl.conf and add a few customized lines below the variable "Listen" at the top of the file.

I tried a few ways to do it, however failed to accomplish what I need.

These are the lines that I need to add into the file after the top most "Listen" variable in the file.

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-XSS-Protection "1; mode=block"
#Header always set Referrer-Policy "same-origin"
Header always set X-Permitted-Cross-Domain-Policies "master-only"
Header unset X-Powered-By
#Header set X-Content-Type-Options "nosniff"

AddOutputFilterByType DEFLATE text/html text/plain text/xml text/javascript application/x-javascript text/css application/javascript

# enable expirations
     ExpiresActive On

# expire files after a day in the client's cache
# expire files after 10 days in the client's cache
     ExpiresByType image/gif A864000
     ExpiresByType image/jpeg A864000
     ExpiresByType image/jpg A864000
     ExpiresByType image/png A864000
     ExpiresByType text/javascript A864000
     ExpiresByType application/x-javascript A864000
     ExpiresByType text/css A864000
     ExpiresByType image/x-icon A864000
     ExpiresByType application/javascript A864000

I use the steps below to add the lines above :

1) arg=$(grep -o -m 1 Listen ssl.conf | head -1)
2) vi add.txt

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-XSS-Protection "1; mode=block"
#Header always set Referrer-Policy "same-origin"
Header always set X-Permitted-Cross-Domain-Policies "master-only"
Header unset X-Powered-By
#Header set X-Content-Type-Options "nosniff"

AddOutputFilterByType DEFLATE text/html text/plain text/xml text/javascript application/x-javascript text/css application/javascript

# enable expirations
     ExpiresActive On

# expire files after a day in the client's cache
# expire files after 10 days in the client's cache
     ExpiresByType image/gif A864000
     ExpiresByType image/jpeg A864000
     ExpiresByType image/jpg A864000
     ExpiresByType image/png A864000
     ExpiresByType text/javascript A864000
     ExpiresByType application/x-javascript A864000
     ExpiresByType text/css A864000
     ExpiresByType image/x-icon A864000
     ExpiresByType application/javascript A864000

3) sed -i '/$arg/r add.txt' ssl.conf

The steps above do not work.

I then tried this :

zabbix-cj:/opt/rh/httpd24/root/etc/httpd/conf.d# awk '/$arg/{print $0 RS \
> "Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"" RS \
> "Header always set X-XSS-Protection "1; mode=block"" RS \
> "Header always set X-Permitted-Cross-Domain-Policies "master-only"" RS \
> "Header unset X-Powered-By";next}1' ssl.conf

This throws error :

awk: cmd. line:2: "Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"" RS \
awk: cmd. line:2:                                                      ^ syntax error

Please help correct the syntax for the steps I took above (if possible), else suggest another way that will produce what I need.

You had the wrong quotes.

sed -i "/$arg/r add.txt" ssl.conf

and the shell will substitute the $arg .

--- Post updated at 11:14 ---

But if you have multiple Listen and want to insert test after the first one only, then it is better to get a line number:

# Get the line numbers for "Listen" and select the 1st one
lineno=$(sed -n '/Listen/=' ssl.conf | sed -n '1p')
# After that line number insert the text
sed -i "${lineno}r add.txt" ssl.conf

How about this one, no $arg needed:

sed -e '1,// {/Listen/r add.txt' -e'}' ssl.conf

which checks from line #1 till /Listen/ is encountered the first time. The trick is "reusing" the "previous regular expression" for the range end definition. /Listen/ will be evaluated for line 1, and can be reused from then on.

This solution worked for me. However, I forgot about adding a new line (empty line) after the "Listen" string.
So the solution above works, but it includes the lines from add.txt immediately (the following line) after the Listen string.

I tried this :

sed -i "${lineno} a \n" ssl.conf

It creates the empty line, but also has \n in that new line.
How do I create only the empty line, without the \n?

Most easy:
let the add.txt begin with an empty line!

If you really want an extra command to add the empty line, then...

The \n handling is a bit strange in GNU sed. The following seems to work:

sed -i "${lineno} a \\\\" ssl.conf

Within a "string" a literal \ needs \\ for the shell to work. Or use a concatenation of "string1" and 'string2'; the sed sees the concatenated string:

sed -i "${lineno}"' a \\' ssl.conf

It is more efficient to do two actions in one stroke. The folllowing is a multi-liner that uses the "correct" (Unix-sed style) appending of an empty line:

sed -i "$lineno"' {
a \

r add.txt
}' ssl.conf

Thank you so much for the suggestions.
Excuse my urge towards creating "eccentric" scripts, but now I need help to use the $HOSTNAME, or `hostname` variable to edit ssl.conf and add the line

"ServerName $MYSERVERHOSTNAME:443"

below the "ServerName" variable.

I have tried the ones below, but it didn't seem to work :

sed  '/ServerName/a \
ServerName' "$HOSTNAME"':443' ssl.conf

 sed  '/ServerName/a \
ServerName `hostname`:443' ssl.conf
host=`hostname`:443
echo $host
linearg=$(sed -n '/ServerName/=' ssl.conf | sed -n '1p')
sed -i ''"$linearg"'a' "ServerName $host"' ssl.conf
1 Like