今天跟同事探讨了一下 shell 脚本中对配置文件的读写问题。在此总结一下常用的配置文件的读写方式。
大多数的配置文件都是以key=value形式存在的。配置项完全由键值对组成。这样的配置文件读写也是最简单的,假如有以下配置文件user.conf:

id=1
name=shaoqiu
phone=1234567890

1. source

配置的读取很简单,只要将其source进来即可:

shaoqiu@shaoqiu-HP440:~/project/shell$ cat setup.sh
#!/bin/bash source user.conf
echo "id = $id"
echo "name = $name"
echo "phone = $phone" shaoqiu@shaoqiu-HP440:~/project/shell$ ./setup.sh
id = 1
name = shaoqiu
phone = 1234567890
shaoqiu@shaoqiu-HP440:~/project/shell$

2. sed

上面的方法看似简单,但可能会有问题,shell的赋值语句=号两边是不能有空格的,万一用户不小心多加了空白符呢。为防止这样的情况出现,还是换另一种写法比较安全:

shaoqiu@shaoqiu-HP440:~/project/shell$ cat user.conf
id=1
name=shaoqiu
phone=1234567890 shaoqiu@shaoqiu-HP440:~/project/shell$ cat setup.sh
#!/bin/bash function get_config() {
local configPath=$1
local configName=$2
sed -n 's/^[[:space:]]*'$configName'[[:space:]]*=[[:space:]]*\(.*[^[:space:]]\)\([[:space:]]*\)$/\1/p' $configPath
} function set_config() {
local configPath=$1
local configName=$2
local confgValue=$3
sed -i 's/^[[:space:]]*'$configName'[[:space:]]*=.*/'$configName'='$confgValue'/g' $configPath
} get_config user.conf name
set_config user.conf name qiushao
get_config user.conf name
shaoqiu@shaoqiu-HP440:~/project/shell$ ./setup.sh
shaoqiu
qiushao
shaoqiu@shaoqiu-HP440:~/project/shell$ cat user.conf
id=1
name=qiushao
phone=1234567890 shaoqiu@shaoqiu-HP440:~/project/shell$

3. section 配置文件读取

假如配置文件是由多个 section 组成的呢,就像下面这样:

[id=1]
name=shaoqiu
phone=1234567890 [id=2]
name=shaojiang
phone=5678901234 [id=3]
name=zhaotong
phone=8901234567

需要根据输入的id来读写相应的配置项。这样就不能简单的使用前面介绍的方法了。遇到这种情况,可以使用下面这种方法,将配置文件拆分成多个,分别存放到不同的目录中:

config
-id1
-user.conf
-id2
-user.conf
-id3
-user.conf

根据id读取不同目录下的配置文件即可。如果配置信息很多的话,推荐使用这种方法,目前在82平台上的机型配置就是使用这种方法来实现的。但若是配置信息很少,且可能有其他脚本也使用到了这个配置文件的时候,拆分配置文件可能就行不通了,需要寻找其他方法。要读写这种格式的配置文件比较复杂,下面是我使用的方法:

shaoqiu@shaoqiu-HP440:~/project/shell$ cat user.conf
[id=1]
name=shaoqiu
phone=1234567890 [id=2]
name=shaojiang
phone=5678901234 [id=3]
name=zhaotong
phone=8901234567 shaoqiu@shaoqiu-HP440:~/project/shell$ cat setup.sh
#!/bin/bash function string_trim()
{
echo "$1" | sed 's/^[[:space:]]*\(.*[^[:space:]]\)\([[:space:]]*\)$/\1/g'
} function get_region() {
local configPath=$1
local userID=$2
cat -n $configPath | grep "\\[id=.*\\]" | grep -A 1 "\\[id=$userID\\]" | awk '{print $1}' | xargs
} function get_config() {
local configPath=$1
local userID=$2
local configName=$3 local region=$(get_region $configPath $userID)
local startLine=$(echo $region | awk '{print $1}')
local endLine=$(echo $region | awk '{print $2}')
string_trim $(sed -n "${startLine}, ${endLine} s/\(${configName}.*=.*\)/\1/p" $configPath | awk -F= '{print $2}')
} function set_config() {
local configPath=$1
local userID=$2
local configName=$3
local confgValue=$4 local region=$(get_region $configPath $userID)
local startLine=$(echo $region | awk '{print $1}')
local endLine=$(echo $region | awk '{print $2}')
sed -i "${startLine}, ${endLine} s/${configName}.*=.*/${configName}=${confgValue}/g" $configPath
} get_config user.conf 2 name
set_config user.conf 2 name qiushao
get_config user.conf 2 name
shaoqiu@shaoqiu-HP440:~/project/shell$ ./setup.sh
shaojiang
qiushao
shaoqiu@shaoqiu-HP440:~/project/shell$

这种方法的思想是先找出指定id的配置所在的区域,即从哪行开始,到哪行结束。只要找到这个区间就好办了,因为sed可以指定只处理的区间。获取区间的方法解释如下:

cat -n $configPath #给每一行加上行号
| grep "\\[id=.*\\]" #打印所有的`id`配置行
| grep -A 1 "\\[id=$userID\\]" #打印匹配的ID行,及下一行,下一行即为下一个配置section的起始行
| awk '{print $1}' | xargs #提取两个行号,即所需section的起始行和下一个配置section的起始行。

这种方法当时也是突发其想,想出来的。现在回头看看,其实使用倒推法应该不难想出这种方法。即最后应该是使用sed处理指定区间的文本。那前提就是需要找出section的区间了。而区间也就是两个行号,自然想到要cat -n了。

shell 读配置文件的更多相关文章

  1. Shell读取配置文件的方法

    参考:http://www.cnblogs.com/binbinjx/p/5680214.html 做批量软件安装自动化时,都喜欢用配置文件的方式改变参数,那怎么通过shell读取配置文件的配置呢?参 ...

  2. java工具类-读配置文件

    ///读配置文件 import java.io.InputStream;import java.util.HashMap;import java.util.Map;import java.util.M ...

  3. shell的配置文件

    1. bash shell 的配置文件 bash shell的配置文件很多,可以分成下面类别 1.1 按生效范围划分两类 全局配置:针对所有用户皆有效 /etc/profile /etc/profil ...

  4. linux bash shell 的配置文件

    按生效范围划分两类 全局配置:针对所有用户皆有效 /etc/profile /etc/profile.d/*.sh /etc/bashrc 个人配置:只针对特定用户有效 ~/.bash_profile ...

  5. linux shell的配置文件执行顺序

    shell配置文件的作用:初始化环境变量.设置命令提示符.指定系统命令路径等 shell配置文件分类: (1)系统级别配置文件: /etc下,比如/etc/profile./etc/bashrc (2 ...

  6. Java Properties 类读配置文件保持顺序

    前几天,公司项目中有一个需求是读取配置文件的,而且最好能够保证加载到内存中的顺序能够和配置文件中的顺序一致,但是,如果使用 jdk 中提供的 Properties 类的话,读取配置文件后,加载到内存中 ...

  7. shell 读取配置文件的方法

    原文地址:http://bbs.chinaunix.net/thread-3628456-1-1.html 总结地址:https://www.cnblogs.com/binbinjx/p/568021 ...

  8. [BUG]读配置文件中文, 查询不到数据库

    配置文件编码, 要和数据库编码一致

  9. 读配置文件property文件

    import java.io.IOException;import java.util.Properties; import org.springframework.core.io.support.P ...

随机推荐

  1. 「6月雅礼集训 2017 Day5」仰望星空

    [题目大意] 给你$n$个点,被一个半径为$R$的元圆划分成内(包含边界).外两个部分. 要连若干线,每个点只能连一条线,不存在重点和三点共线. 线只能连在内部点和外部点之间,线长度不超过$d$. 如 ...

  2. js获取屏幕高度宽度

    获取各种屏幕的宽度和高度Javascript: 网页可见区域宽: document.body.clientWidth网页可见区域高: document.body.clientHeight网页可见区域宽 ...

  3. vue双向绑定原理源码解析

    当我们学习angular或者vue的时候,其双向绑定为我们开发带来了诸多便捷,今天我们就来分析一下vue双向绑定的原理. 简易vue源码地址:https://github.com/maxlove123 ...

  4. nodejs入门教程之http的get和request简介及应用

    nodejs入门教程之http的get和request简介及应用 前言 上一篇文章,我介绍了nodejs的几个常用的模块及简单的案例,今天我们再来重点看一下nodejs的http模块,关于http模块 ...

  5. js_参数的get传输,从一个页面到另外一个页面。

    2017年10月31日,今天是万圣节,欢乐谷搞事情. 刚接触前端那会是分不清,前端和后台的,后台的数据如何传输到前端的. 现在用的还是Jquery的ajax请求后台数据到前端页面的,需要学习的地方还有 ...

  6. Android中的异常情况

    1.setText()方法中,如果参数是int类型,Android会把它当做是一个id查找,报以下异常,因此解决办法就是将参数转化为String类型 如:setText(num) è setText( ...

  7. %和format 细说

    Python中格式化字符串目前有两种阵营:%和format,我们应该选择哪种呢? 自从Python2.6引入了format这个格式化字符串的方法之后,我认为%还是format这根本就不算个问题.不信你 ...

  8. linux之cron定时任务介绍

    前言 linux系统有一个专门用来管理定时任务的进程cron,一般是设置成开机自启动的,通过添加任务可以让服务器定时执行某些任务. cron介绍 linux系统有一个专门用来管理定时任务的进程cron ...

  9. Meld:文件及目录对比工具

    Meld:文件及目录对比工具 http://wowubuntu.com/meld.html http://meld.sourceforge.net/

  10. 更新T1表,要添加一个条件A,但T1表没有A字段

    可以这样 如果T2表有A字段,T1.T2表有共同字段B,可以通过T2表A字段为条件查得B字段 再用B字段为条件去更新T1表 update T1 set C = '1' where B in(selec ...