在 RHEL6.7 上用 sed 替换 sed

Replacing sed with sed on RHEL6.7

我正在尝试用 sed 命令替换 sed 命令,但它一直失败,所以在 "picket fencing" 几个小时后我想我会在这里问这个问题。

我有各种 bash 脚本包含这种行:

 sed 's/a hard coded server name servername.//'

我想将其替换为:

 sed "s/a hard coded server name $(hostname).//"

注意添加双引号以便扩展 $(hostname),这比我预期的要复杂一些。

所以这是我多次失败尝试中的第一次:

cat file | sed 's!sed \'s\/a hard coded server name servername.\/\/\'!sed \"s\/a hard coded server name $(hostname).\/\/\"!g'

我还尝试使用 sed 的“-e”选项将替换分解成多个部分以尝试定位问题区域。我不会在解决方案中使用“-e”开关,但它有时对调试很有用:

cat file | sed -e 's!servername!$\(hostname\)!' -e 's!\| sed \'s!\| sed \"s!'

第一个 sed 按预期工作(这里没有什么特别的事情发生),第二个失败,所以没有必要添加第三个,它必须替换结束双引号。

在这一点上,我的历史陷入混乱,所以没有必要再添加任何失败的尝试。

我想在单个命令中使用第一个替换,因为脚本中充满了 sed 命令,而我只想针对脚本中的一个特定命令。

如有任何想法,我们将不胜感激。

通过使用不应在实际使用中出现的序列并替换它来遵循模板工具的行为。例如,使用冒号只是因为它们需要较少的引号:

#!/bin/bash
sed "s/:servername:/$(hostname)/g" <<EOF > my_new_script.bash
  echo "This is :servername:"
EOF

为了清楚起见,我在内部脚本中使用了 echo。你同样可以使用类似的东西:

sed 's/complex substitution :servername:/inside quotes :servername:/'

这避免了引用麻烦,因为外部 sed 将此处的文档视为纯文本。

如果像使用 sed 一样忽略(或处理)新旧文本中的元字符,您可以在 awk 中执行此操作:

$ awk -v old="sed 's/a hard coded server name servername.//'" \
      -v new="sed 's/a hard coded server name '\"$(hostname)\"'.//' \
          '{sub(old,new)}1' file
sed 's/a hard coded server name '"$(hostname)"'.//'

或者为了避免必须处理元字符,仅使用字符串进行比较和替换:

$ awk -v old="sed 's/a hard coded server name servername.//'" \
      -v new="sed 's/a hard coded server name '\"$(hostname)\"'.//'" \
          's=index([=11=],old){[=11=]=substr([=11=],1,s-1) new substr([=11=],s+length(old))}1' file
sed 's/a hard coded server name '"$(hostname)"'.//'