Home > Software engineering >  Many lines with indentation in sed's substitute
Many lines with indentation in sed's substitute

Time:12-16

How can I persist indentation in the multiline string used in sed?

What I'm doing is:

FILES_MATCH='<FilesMatch \\.php\$>\nSetHandler "proxy:unix:\/var\/run\/php\/php7.3-fpm.sock|fcgi:\/\/localhost"\n<\/FilesMatch>'
sed -i '' "s/ProxyPassMatch .*/${FILES_MATCH}/" "$HOME/Projects/${DIR_NAME}/deploy/apache/default.conf"

As a result I'm getting:

        <FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php7.3-fpm.sock|fcgi://localhost"
</FilesMatch>

Of course it should look like this:

<FilesMatch \.php$>
    SetHandler "proxy:unix:/var/run/php/php7.3-fpm.sock|fcgi://localhost"
</FilesMatch>

How can I control indentation in multiline substitution?

CodePudding user response:

How can I control indentation in multiline substitution?

You are literally substituting the text.

FILES_MATCH='<...>\n     SetHandler....'
#                    ^^^^^ - spaces
sed -i '' "s/ *ProxyPassMatch .*/${FILES_MATCH}/" 
#            ^^ - remove leading spaces

Ugh this is so hard with all the \n and \/\/\/\/\/. Consider using awk or python or perl. For starters use a different separator.

files_match='no need to escape //// characters now'
sed "s! *ProxyPassMatch .*!${FILES_MATCH}!"
#     ^                   ^              ^ - you can use any character

$ is literally $, no need to escape it.

CodePudding user response:

You can capture the leading indentation in a group and apply it to the beginning of each line as you substitute, e.g.:

FILES_MATCH='\1<FilesMatch \\.php\$>\n\1    SetHandler "proxy:unix:\/var\/run\/php\/php7.3-fpm.sock|fcgi:\/\/localhost"\n\1<\/FilesMatch>'
sed "s/^\\([ \t]*\\)ProxyPassMatch .*/${FILES_MATCH}/"

The group \([ \t]\) captures any leading spaces and tabs before ProxyPassMatch and each \1 is substituted by the same. You need to add the additional indentation before SetHandler yourself.

  • Related