sed编辑配置脚本中的字段

时间:2014-07-15 15:13:59

标签: bash sed

自从我编辑了一个shell脚本以来已经有一段时间了,所以请耐心等待。我有一个用于数据库故障转移的脚本,我试图使其更加智能化。其中一行读取类似

的内容
primary_connection = 'host=10.10.1.129 port=5033'

我需要更改主机的值。问题是值可以是显示的IP地址,也可以是名称。由于这是shell脚本的一部分,我真的需要使用sed或其他简单易用的命令来改变它。其他选项如perl或python在这个系统上是不可用的。我尝试了几种不同的正则表达式模式,但似乎无法正确识别语法并且出错。

3 个答案:

答案 0 :(得分:2)

鉴于

$ cat file
hello
primary_connection = 'host=10.10.1.129 port=5033'
bye

您可以使用:

$ sed -r "s/(primary_connection[ ]*=[ ]*'host=)[^ ]*/\1t/" file
hello
primary_connection = 'host=t port=5033'
bye

或更复杂:

$ sed -r "s/(primary_connection[ ]*=[ ]*'host[ ]*=)[^ ]*/\1t/" file
hello
primary_connection = 'host=t port=5033'
bye

要进行就地编辑,请添加-i.bak。这会将文件备份到file.bak,然后file会更新。

答案 1 :(得分:2)

sed "s/something/$variable/"这样的结构的缺点之一是,如果$variable包含斜杠,您的脚本会失败,如果有人能够恶意修改该变量,他们可能会插入代码将由您的sed脚本运行。

通常,您不希望使用尚未检查有效性的变量。因此,只给出基于sed的解决方案的答案是一个开始,但不完整。

由于您使用标记了问题,因此这是一个仅在bash中运行的解决方案。它非常明确,以避免出现像数据库冗余那样极其重要的错误。

#!/bin/bash

# You'd likely get this from $1, or elsewhere...
newhost="10.1.1.1"

# Use "extglob" extended pattern matching...
shopt -s extglob

# Go through each line of the input file...
while read line; do

  # Recognize the important configuration line...
  if [[ "$line" =~ ^primary_connection\ =\  ]]; then

    # Detect the field to change, AND validate our input.
    if [[ "$line" =~ host=[^\ ]+ ]] && [[ "$newhost" =~ ^[a-z0-9.-]+$ ]]; then
      line="${line/host=+([^ ])/host=$newhost}"
    fi

  fi

  # Output the current (possibly modified) line.
  echo "$line"

done < inputfile

此脚本的输出是替换主机的输入文件。您可以弄清楚如何安全地移动旧文件并将新文件复制到位。

请注意,我们只允许在主机名中使用字母数字,句点和连字符,这应该足以允许主机名和IP地址。

我使用以下inputfile进行了测试:

foo
# primary_connection is a string.
primary_connection = 'host=10.10.1.129 port=5033'
bar

请注意,因为正则表达式识别&#34;重要的配置行&#34;以克拉为基础,我们不会冒着改变评论线的风险。如果您选择基于sed的答案,则应考虑使用类似的锚点。

答案 2 :(得分:1)

您可以使用:

sed -i.bak "/primary_connection/s/\(host=\)[^[:blank:]]*/\1$new_host_name/" file