我已经很久没有编辑shell脚本了,所以请耐心点。我有一个用于数据库故障转移的脚本,我正试图使它更加智能化。其中的一行读起来像是
primary_connection = 'host=10.10.1.129 port=5033'我需要更改主机的值。问题是,值可以是所示的IP地址,也可以是名称。由于这是shell脚本的一部分,我确实需要使用sed或另一个简单的、随时可用的命令来更改它。其他选项,如perl或python,在此系统中不可用。我尝试过几种不同的regex模式,但似乎无法得到正确的语法和错误。
发布于 2014-07-15 15:19:09
给定的
$ 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。
发布于 2014-07-15 18:39:57
像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请注意,因为识别“重要配置线”的正则表达式是用克拉锚定的,所以我们不会冒险更改注释行。如果选择基于sed的答案,则应考虑使用类似的锚点。
发布于 2014-07-15 15:19:03
您可以使用:
sed -i.bak "/primary_connection/s/\(host=\)[^[:blank:]]*/\1$new_host_name/" filehttps://stackoverflow.com/questions/24761889
复制相似问题