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

时间:2017-11-30 20:27:33

标签: bash sed heredoc

我试图直接在[PHP]行下面的php.ini文件顶部写一个heredoc。假设以下条件,我也尝试这样做:

  1. [PHP]可能不是最顶层的(在其他用例中,知道如何将heredoc放在文件中的任何位置后很高兴,所以指定'第2行' isn&# 39;非常有用
  2. heredoc必须包含在文件中。没有使用sed打开另一个文件并将其读入现有文件
  3. 假设[PHP]标识符只有一个实例。在这个学习练习中,我不担心迭代列表,或者Sed / Awk发现我的搜索字符串不止一个实例
  4. 我真的很想让每个项目都在自己的行中,就像在heredoc中一样
  5. 脚本:

    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
    

    在我尝试过的每一次迭代中,我最终都得到了一个像这样的php.ini:

    [PHP]
    $myvar
    

    或者,我收到以下错误:

    sed: -e expression #1, char 15: unknown command: `e'
    

    我的目标是:

    [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
    

3 个答案:

答案 0 :(得分:2)

虽然可以使用sed完成此任务,但sed不是最佳选择。它不支持变量。每当必须在sed命令中包含shell变量时,就会打开潜在的安全漏洞。相比之下,Awk非常适合这项任务。如果您有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

结果是:

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

如果您的awk不支持GNU的-i inplace选项,请将awk行替换为:

awk -v x="$myvar" '{print} /\[PHP\]/{print x}' php.ini >tmp && mv tmp php.ini

注释

如上所示,

myvar可以直接定义,而无需使用cat或here-docs。

答案 1 :(得分:1)

您可以使用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

答案 2 :(得分:0)

有时,好的ed也可能会有所帮助。像:

(
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

编辑 - 更简单(没有&#34;动态&#34;):)

ed -s php.ini >/dev/null <<'END_HEREDOC'
/^\[PHP\]/
i
[xdebug]
zend_extension=/usr/lib/php/20151226/xdebug.so
.
w
q
END_HEREDOC