自从我编辑了一个shell脚本以来已经有一段时间了,所以请耐心等待。我有一个用于数据库故障转移的脚本,我试图使其更加智能化。其中一行读取类似
的内容primary_connection = 'host=10.10.1.129 port=5033'
我需要更改主机的值。问题是值可以是显示的IP地址,也可以是名称。由于这是shell脚本的一部分,我真的需要使用sed或其他简单易用的命令来改变它。其他选项如perl或python在这个系统上是不可用的。我尝试了几种不同的正则表达式模式,但似乎无法正确识别语法并且出错。
答案 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标记了问题,因此这是一个仅在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