问题
I'm attempting to write a heredoc at the top of my php.ini file directly under the [PHP] line. I'm also attempting to do it assuming the following conditions:
- [PHP] might not be at the very top (in other use cases, it would be nice to know how to put a heredoc anywhere in a file after something, so specifying 'line 2' isn't really useful
- The heredoc has to be contained in the file. No use of sed where another file is opened and read into the existing file
- Assume there is only one instance of the [PHP] identifier. In this learning exercise, I'm not worried about iterating a list, or Sed / Awk finding more than one instance of my search string
- I'd really like to have each item on its own line just like in the heredoc
Script:
myvar=$(cat << END_HEREDOC
[xdebug]
zend_extension=/usr/lib/php/20151226/xdebug.so
xdebug.remote_host = localhost
xdebug.idekey = "PHPSTORM"
xdebug.remote_autostart = 1
xdebug.remote_connect_back = 1
xdebug.remote_enable=1
xdebug.remote_port=9000
xdebug.show_local_vars=0
xdebug.var_display_max_data=10000
xdebug.var_display_max_depth=20
xdebug.show_exception_trace=0
xdebug.remote_handler=dbgp
END_HEREDOC
)
echo ${myvar}
sed -i "/\[PHP\]'/${myvar}/'" php.ini
In every iteration I've tried, I simply end up with a php.ini looking like this:
[PHP]
$myvar
Or, I get the following error:
sed: -e expression #1, char 15: unknown command: `e'
My goal is:
[PHP]
[xdebug]
zend_extension=/usr/lib/php/20151226/xdebug.so
xdebug.remote_host = localhost
xdebug.idekey = "PHPSTORM"
xdebug.remote_autostart = 1
xdebug.remote_connect_back = 1
xdebug.remote_enable=1
xdebug.remote_port=9000
xdebug.show_local_vars=0
xdebug.var_display_max_data=10000
xdebug.var_display_max_depth=20
xdebug.show_exception_trace=0
xdebug.remote_handler=dbgp
回答1:
While this task can be done with sed, sed is not optimal. It does not support variables. Anytime one has to encorporate shell variables within a sed command, one opens potential security flaws. Awk, by contrast, is well-suited to this task. If you have GNU awk (gawk), try:
$ cat script.sh
myvar='
[xdebug]
zend_extension=/usr/lib/php/20151226/xdebug.so
xdebug.remote_host = localhost
xdebug.idekey = "PHPSTORM"
xdebug.remote_autostart = 1
xdebug.remote_connect_back = 1
xdebug.remote_enable=1
xdebug.remote_port=9000
xdebug.show_local_vars=0
xdebug.var_display_max_data=10000
xdebug.var_display_max_depth=20
xdebug.show_exception_trace=0
xdebug.remote_handler=dbgp
'
awk -i inplace -v x="$myvar" '{print} /\[PHP\]/{print x}' php.ini
The result is:
$ cat php.ini
[PHP]
[xdebug]
zend_extension=/usr/lib/php/20151226/xdebug.so
xdebug.remote_host = localhost
xdebug.idekey = "PHPSTORM"
xdebug.remote_autostart = 1
xdebug.remote_connect_back = 1
xdebug.remote_enable=1
xdebug.remote_port=9000
xdebug.show_local_vars=0
xdebug.var_display_max_data=10000
xdebug.var_display_max_depth=20
xdebug.show_exception_trace=0
xdebug.remote_handler=dbgp
BSD/OSX or other non-GNU awk
If your awk does not support GNU's -i inplace
option, then replace the awk line with:
awk -v x="$myvar" '{print} /\[PHP\]/{print x}' php.ini >tmp && mv tmp php.ini
Notes
myvar
can be defined directly, as shown above, without using cat
or here-docs.
回答2:
You can use the sed r
command which inserts text from a file, but use process substitution to replace the filename with the heredoc:
#!/bin/bash
sed -i '' '/\[PHP]/r '<(cat << END_HEREDOC
[xdebug]
zend_extension=/usr/lib/php/20151226/xdebug.so
xdebug.remote_host = localhost
xdebug.idekey = "PHPSTORM"
xdebug.remote_autostart = 1
xdebug.remote_connect_back = 1
xdebug.remote_enable=1
xdebug.remote_port=9000
xdebug.show_local_vars=0
xdebug.var_display_max_data=10000
xdebug.var_display_max_depth=20
xdebug.show_exception_trace=0
xdebug.remote_handler=dbgp
END_HEREDOC
) php.ini
回答3:
Sometimes the good old ed
could be also helpful. Like:
(
printf '%s\n' '/^\[PHP\]/' i
cat <<'END_HEREDOC'
[xdebug]
zend_extension=/usr/lib/php/20151226/xdebug.so
...
END_HEREDOC
printf '%s\n' . w q
) | ed -s php.ini > /dev/null
EDIT - simpler (nothing "dynamic") :)
ed -s php.ini >/dev/null <<'END_HEREDOC'
/^\[PHP\]/
i
[xdebug]
zend_extension=/usr/lib/php/20151226/xdebug.so
.
w
q
END_HEREDOC
来源:https://stackoverflow.com/questions/47582028/trying-to-write-a-heredoc-into-an-existing-file-using-sed-in-bash