bash 中尝试使用 Sed 将 heredoc 写入现有文件
Trying to write a heredoc into an existing file using Sed in bash
我正试图在我的 php.ini 文件顶部的 [PHP] 行正下方写一个 heredoc。我也在尝试假设以下条件:
- [PHP] 可能不在最上面(在其他用例中,很高兴知道如何在文件中的某处之后放置 heredoc,因此指定 'line 2'不是很有用
- heredoc 必须包含在文件中。在打开另一个文件并读入现有文件的情况下不使用 sed
- 假设只有一个 [PHP] 标识符实例。在这个学习练习中,我不担心迭代列表,或者 Sed / Awk 找到我的搜索字符串的多个实例
- 我真的很想像在 heredoc 中一样让每一项都独占一行
脚本:
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
虽然可以使用 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.
有时,老好人 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
编辑 - 更简单(没什么 "dynamic"):)
ed -s php.ini >/dev/null <<'END_HEREDOC'
/^\[PHP\]/
i
[xdebug]
zend_extension=/usr/lib/php/20151226/xdebug.so
.
w
q
END_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
我正试图在我的 php.ini 文件顶部的 [PHP] 行正下方写一个 heredoc。我也在尝试假设以下条件:
- [PHP] 可能不在最上面(在其他用例中,很高兴知道如何在文件中的某处之后放置 heredoc,因此指定 'line 2'不是很有用
- heredoc 必须包含在文件中。在打开另一个文件并读入现有文件的情况下不使用 sed
- 假设只有一个 [PHP] 标识符实例。在这个学习练习中,我不担心迭代列表,或者 Sed / Awk 找到我的搜索字符串的多个实例
- 我真的很想像在 heredoc 中一样让每一项都独占一行
脚本:
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
虽然可以使用 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.
有时,老好人 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
编辑 - 更简单(没什么 "dynamic"):)
ed -s php.ini >/dev/null <<'END_HEREDOC'
/^\[PHP\]/
i
[xdebug]
zend_extension=/usr/lib/php/20151226/xdebug.so
.
w
q
END_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