简体   繁体   English

尝试使用bash中的Sed将heredoc写入现有文件

[英]Trying to write a heredoc into an existing file using Sed in bash

I'm attempting to write a heredoc at the top of my php.ini file directly under the [PHP] line. 我正在尝试直接在[PHP]行下面的php.ini文件顶部写一个heredoc。 I'm also attempting to do it assuming the following conditions: 假设满足以下条件,我也会尝试这样做:

  1. [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 [PHP]可能不是最顶层的(在其他用例中,知道如何将heredoc放在文件后面的任何地方会很好,所以指定'第2行'并不是很有用
  2. The heredoc has to be contained in the file. heredoc必须包含在文件中。 No use of sed where another file is opened and read into the existing file 没有使用sed打开另一个文件并将其读入现有文件
  3. Assume there is only one instance of the [PHP] identifier. 假设[PHP]标识符只有一个实例。 In this learning exercise, I'm not worried about iterating a list, or Sed / Awk finding more than one instance of my search string 在这个学习练习中,我不担心迭代列表,或者Sed / Awk发现我的搜索字符串的多个实例
  4. I'd really like to have each item on its own line just like in the heredoc 我真的希望每个项目都在自己的行上,就像在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.ini看起来像这样:

[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

While this task can be done with sed, sed is not optimal. 虽然可以使用sed完成此任务,但sed不是最佳的。 It does not support variables. 它不支持变量。 Anytime one has to encorporate shell variables within a sed command, one opens potential security flaws. 每当必须在sed命令中包含shell变量时,就会打开潜在的安全漏洞。 Awk, by contrast, is well-suited to this task. 相比之下,Awk非常适合这项任务。 If you have GNU awk (gawk), try: 如果您有GNU awk(gawk),请尝试:

$ 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 BSD / OSX或其他非GNU awk

If your awk does not support GNU's -i inplace option, then replace the awk line with: 如果你的awk不支持GNU的-i inplace选项,那么用以下代码替换awk行:

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. myvar可以直接定义,如上所示,不使用cat或here-docs。

You can use the sed r command which inserts text from a file, but use process substitution to replace the filename with the heredoc: 您可以使用sed r命令从文件中插入文本,但使用进程替换将文件名替换为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

Sometimes the good old ed could be also helpful. 有时,好的旧ed也可能有所帮助。 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM