Linux脚本解析属性文件
Contents
1. 概述
属性文件包含点分隔字符串形式的属性名称。
这种结构很好地捕捉了属性的层次结构。但是,在 bash 脚本中直接使用这些名称是很困难的。
在本教程中,我们将通过尽可能少地更改其名称结构来访问此类属性。
2. 问题陈述
让我们检查一个简单的属性文件test.properties:
# test.properties
db.test.user=test user
db.test.passwd=password
作为第一次尝试,让我们将属性名称转换为 bash 变量。为此,我们只*source *属性文件:
#!/bin/bash
source test.properties
echo "User Id (db.test.user) = " $db.test.user
echo "user password (db.test.passwd) =" $db.test.passwd
不幸的是,我们最终会遇到错误:
test.properties: line 2: db.test.user=test user: command not found
test.properties: line 3: db.test.passwd=password: command not found
User Id (db.test.user) = .test.user
user password (db.test.passwd) = .test.passwd
这种方法失败了,因为点是 bash 变量名称中的非法字符。
3. 从属性名称中映射出点
让我们把点变成一些合法的字符。
bash 变量的名称只能包含数字、字母和下划线。因此我们需要选择下划线’_’:
#!/bin/sh
file="./test.properties"
while IFS='=' read -r key value
do
key=$(echo $key | tr '.' '_')
eval ${key}=\${value}
done < "$file"
echo "User Id (db.test.user) = " ${db_test_user}
echo "user password (db.test.passwd) = " ${db_test_passwd}
我们分别*read * key和value,用等号作为分隔符。接下来,tr 将属性名称中的点转换为下划线。最后,eval 定义了一个具有新名称的 bash 变量。
现在让我们检查这个脚本产生的结果:
User Id (db.test.user) = test user
user password (db.test.passwd) = password
在这种方法中,我们创建了一堆 bash 变量,每个属性一个。随后,我们使用映射名称来引用属性。
4. 使用数组作为查找表
从 Bash 4.0 开始,我们可以从关联数组 中受益。因此,让我们使用属性的名称作为其值的键:
#!/bin/bash
# array declaration
declare -A props
file="./test.properties"
while IFS='=' read -r key value; do
props["$key"]="$value"
done < "$file"
echo "User Id (db.test.user) = " ${props["db.test.user"]}
echo "user password (db.test.passwd) = " ${props["db.test.passwd"]}
key的形式没有限制。因此,我们可以使用自己的名称访问属性。
5. 使用包装函数从文件中提取变量
让我们创建一个在属性文件中搜索属性名称的函数。结果,它返回属性的值。
在后台,我们将使用grep 命令并随后从找到的行中cut 属性值:
#!/bin/bash
file="./test.properties"
function prop {
grep "${1}" ${file} | cut -d'=' -f2
}
echo "User Id (db.test.user) = " $(prop 'db.test.user')
echo "user password (db.test.passwd) = " $(prop 'db.test.passwd')
我们使用其原始名称来引用该属性。但是,每次选择变量都需要再次对整个文件进行 grep。因此,对于大型属性文件,此方法可能会很慢。