Skip to content
Advertisement

sed command string variable concatenation within single quotes

I want to modify the include_path directive in my php.ini file using sed. Below, I’ve got a command that looks for a string and places the directive on a line after the match. However, I cannot get it to work while still maintaining the double quotes within the ${install_path} variable. The double quotes must be there.

The file I want to edit is php.ini. Here are a few lines before and after my target, which is the line right after “UNIX: “:

;;;;;;;;;;;;;;;;;;;;;;;;;
; Paths and Directories ;
;;;;;;;;;;;;;;;;;;;;;;;;;

; UNIX: "/path1:/path2"
;include_path = "/path1:/path2"
;
; Windows: "path1;path2"

install_path is defined as:

install_path="/var/www/mainapp"

And the sed command I am using below searches for a string match and then creates a new line right below it:

sed -i '/; UNIX: "/path1:/path2"/a include_path = "${install_path}/lib"' /etc/php.ini

The expected output within php.ini is:

; UNIX: "/path1:/path2"
include_path = "/var/www/mainapp/lib"

Where the include_path line has been created right after the line “; UNIX:…”

Thanks for your help.

Advertisement

Answer

Your main problem is dancing around the quoting conventions of the shell while preserving the quotes in the file.

You say you’ve defined install_path="/var/www/mainapp"; note that the quotes were removed by the shell so the string contains no quotes. That’s important below. Compare the old and the new:

Old:

sed -i '/; UNIX: "/path1:/path2"/a include_path = "${install_path}/lib"' /etc/php.ini

New:

sed -i '/; UNIX: "/path1:/path2"/a include_path = "'"${install_path}/lib"'"' /etc/php.ini

Eh what? You’ve correctly enclosed your script in single quotes, but that prevents the shell from expanding ${install_path}. So, you have to terminate the single-quoted string, but you want double quotes in the output, so I placed the single quote after the double quote. Then I wrapped the value in ${install_path} in double quotes too: "${install_path}/lib". The double quotes are not crucial for the value you quote, but in general it is a good idea to use them. I then resume the single-quoting, and the first character is the closing double quote for the include path string in the .ini file, and then close the single quoted string. Yes, there are other ways you could write that last bit, but it would take considerable persuasion to convince me that alternatives using backslashes are better.

If you actually had preserved the double quotes around the install path value:

install_path='"/var/www/mainapp"'

you could use:

sed -i '/; UNIX: "/path1:/path2"/a include_path = '"${install_path}/lib" /etc/php.ini

Also note that only GNU sed allows you to put ‘appended text’ on the same line as the a command. POSIX sed does not, and other variants of sed on other platforms will not. For instance, on Mac OS X, you’d have to write:

sed -i '/; UNIX: "/path1:/path2"/a
include_path = '"${install_path}/lib" /etc/php.ini
Advertisement