bash 多行 Heredoc(带 Sed)的正确语法是什么?

What is the correct syntax for a bash multi line Heredoc (w/ Sed)?

在使用 Sed 搜索/插入配置文件时,遇到错误。是什么原因造成的,我该如何解决?

我要插入的 Heredoc 可以定义如下:

read -d '' APPLICATION_ENV_STATE <<'EOF'
defined('APPLICATION_ENV') || define('APPLICATION_ENV',(getenv('APPLICATION_ENV') 
    ? getenv('APPLICATION_ENV') : 'production'));
EOF

虽然我的 Sed 命令使用这样的变量:

sed -i "/\/\/ \*\* MySQL settings \*\* \/\//i$APPLICATION_ENV_STATE" wp-config.php

这导致:

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

除了命令错误后多了一个字符。

然而,以下 Heredoc 有效,但导致我的文本文件中的格式不太漂亮:

read -d '' APPLICATION_ENV_STATE <<'EOF'
defined('APPLICATION_ENV') || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));
EOF  

如何让第一个示例起作用?

AIUI,问题不在于 heredoc,在于理解哪个 进程在不同时间做什么。

在运行 sed 命令的脚本中,Bash 甚至在 sed 看到它之前就替换了变量。作为一个多行字符串,它需要转义 sed)。来自 man page for sed,在 i 命令下:

i \     Insert text, which has each embedded newline preceded by a back-slash.

就我个人而言,如果可以的话,我建议使用 cat 或回显(或像 Python / Ruby / PHP 这样的脚本语言),打破了模板化为原子元素,因此您可以简单地将相关部分连接在一起。

如果您确实想要继续当前的方法,您至少需要用反斜杠换行符替换换行符 - 尝试类似的方法:

echo $APPLICATION_ENV_STATE | sed 's/$/\/'

你用错了工具。您应该在 sed 中使用的唯一结构是 s、g 和 p(带有 -n)。只需使用 awk 并避免所有 quoting/escaping 废话:

$ cat file
foo
// ** MySQL settings ** //
bar

$ awk -v app="defined('APPLICATION_ENV') || define('APPLICATION_ENV',(getenv('APPLICATION_ENV')
    ? getenv('APPLICATION_ENV') : 'production'));" '
{print} index([=10=],"// ** MySQL settings ** //"){print app}' file
foo
// ** MySQL settings ** //
defined('APPLICATION_ENV') || define('APPLICATION_ENV',(getenv('APPLICATION_ENV')
    ? getenv('APPLICATION_ENV') : 'production'));
bar

请注意,您不需要转义要搜索的字符串中的 RE 元字符,因为 awk 可以将字符串视为字符串,并且您不需要转义要添加的字符串中的换行符而且您不需要带有 shell 变量等的此处文档

您编写的 read/sed 命令会因搜索中的各种字符组合而失败 and/or 替换字符串 - 请参阅 以了解如何稳健地 search/replace "strings" 在 sed 中,但随后只需使用 awk,这样您就不必担心任何问题。