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

时间:2015-06-08 09:27:50

标签: bash sed multiline heredoc

使用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  

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

2 个答案:

答案 0 :(得分:1)

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或echo,如果可以的话(或像Python / Ruby / PHP这样的脚本语言),将模板分解为原子元素,这样你就可以简单地连接相关的部分。

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

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

答案 1 :(得分:1)

您使用了错误的工具。您应该在sed中使用的唯一构造是s,g和p(使用-n)。只需使用awk并避免所有引用/转义废话:

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

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

请注意,您不需要在要搜索的字符串中转义RE metachars,因为awk可以将字符串视为字符串而您不需要在字符串中转义换行符#&# 39;重新添加,你不需要这里带有shell变量等的doc。

对于搜索和/或替换字符串中的各种字符组合,所写的read / sed命令将失败 - 请参阅Is it possible to escape regex metacharacters reliably with sed了解如何健壮地搜索/替换&#34;字符串&#34;在sed中然后只使用awk,所以你不必担心任何问题。