Shell脚本读取配置文件

Shell脚本读取配置文件

这里参考了下面这篇博客
https://blog.csdn.net/liubeck/article/details/7497156
不过按照上面的代码好像有点问题,后来搞了半天实现了需求。
配置文件为myconfig.ini

[Class]
ids=student1,student2,student3
files=profilefile
 
[student1]
name=LiLei
age=16
 
[student2]
name=HanMeiMei
age=15
 
[student3]
name=Lucy
age=15

如何取[student1]下面name的值呢?用下面这行代码:

awk -F '=' '/\[student1\]/{a=1}a==1&&$1~/name/{print $2;exit}' myconfig.ini 

这句指令涉及到的内容挺多的,查了半天才搞明白,详细解释一下:

  1. 首先这句指令用了awk命令,awk命令通常是将所列出的行,根据条件打印出某一列或几列,想多了解的话可以参考下网上资料
    https://www.cnblogs.com/ftl1012/p/9250541.html

  2. “-F” 是awk命令的一个选项,用来指定后面记录(行)的分隔符号,就是确定用什么作为分隔符号把记录分成一个一个的域,这里后面跟的 ‘=’ 表示用等号来分隔。

  3. 再往后单引号中间是awk命令,awk命令由模式和动作组成,模式是一组用来测试输入行是否需要执行动作的规则,动作是包含语句、函数和表达式的执行过程,简单来说就是模式决定动作何时触发和触发事件,动作执行对输入行的处理。

  4. / \ [student1 \ ]/ 这就是上面说的awk命令的模式,模式与动作之间用 / 来分开,表示匹配到这个模式的话执行后面的动作,这里要匹配的是 [strudent1] ,因为方括号[ ] 在shell中有特殊的意义,使用转义符号\ 表示单纯的 [ ] 符号,所以这里就是[strudent1] 。

  5. {a=1} 花括号里面的内容是awk命令的动作,这里就是给a赋值为1.

  6. a==1&&$1~/name/ 这里又是一个模式匹配,先是判断a是否等于1(因为刚才已经给a赋值为1,所以这里肯定相等),还要$1~/name/,$1表示第一域,就是字符串用分隔符号分割后的第一段, ~ 符号在awk命令中是关系运算符号,表示匹配正则表达式,这里就是要第一域为name

  7. {print $2;exit} 这里又是一个动作,打印第二域,即第一域name的取值,然后退出awk命令。

  8. myconfig.ini 当然表示对 myconfig.ini 文件的操作。
    这句话整体的含义就是: 对 myconfig.ini 文件进行操作,用=对每一行进行分割,找到匹配[student1]的section,再从 [student1] 下面找到name这一opiton,最后打印option的取值。

有了这句话,现在就可以使用shell脚本对 myconfig.ini 文件进行操作了:
configOperate.sh

#!/bin/bash
getconfig()
{
  Section=$1  #传递的第一个参数
  ConFile=$2  #传递的第二个参数
  Options="name\tage\t"
  echo $Options|tr '\\t' '\t'
  for loop in $(echo $Options|tr '\\t' ' ') #tr替换命令
  do
       #{gsub(/[[:blank:]]*/,"",$2)去除值两边的空格内容
       awk -F '=' '/\['"$Section"'\]/{a=1}a==1&&$1~/'"$loop"'/{gsub(/[[:blank:]]*/,"",$2);printf("%s\t\t",$2) ;exit}' $ConFile
  done
}

#更改变量名称
CONFIGFILE=$1
#文件名称
echo -e "ConfigName:$CONFIGFILE \n"
#取得ids中的每个id把,号分隔改成空格,因为循环内容要以空格分隔开来
profile=`sed -n '/ids/'p $CONFIGFILE | awk -F=  '{print $2}' | sed 's/,/ /g'`
#对于一个配置文件中的所有id循环
for stdudent in $profile
do
  echo "--------------------------------------------------"
  echo "student:$stdudent"
  getconfig  $stdudent  $CONFIGFILE
  echo -e "\n"
done

脚本的解释:
首先定义了getconfig()函数,用来将选定的section中的每个option以及取值打印出来。其中的$1、$2是调用函数时传递给它的第一个和第二个参数。

下面两句

  Options="name\tage\t"
  echo $Options|tr '\\t' '\t'

这两句是为了打印两个option :name和age

tr '\\t' '\t'

tr命令用于替换,这里是将 \t 这两个普通符号替换成了制表符号tab,注意\t的用法,因为\符号除了是一个普通符号之外还表示转义字符,所以用转义字符 \ 将它本身转化视作一个普通的符号。
这两句的结果是输出

name		age	

下面一句

  for loop in $(echo $Options|tr '\\t' ' ') 

这句的意思就是循环中让loop分别取name和age
也可以这样写

  for loop in name age

但是不能用

  for loop in `echo $Options|tr '\\t' ' '`  # ` 执行符号

虽然在这句话中能实现的作用一样,但是放到整个脚本中却会有问题,不清楚为什么。

有了之前的解释,这一句

awk -F '=' '/\['"$Section"'\]/{a=1}a==1&&$1~/'"$loop"'/{gsub(/[[:blank:]]*/,"",$2);printf("%s\t\t",$2) ;exit}' $ConFile

就好理解了,不同之除就是如果用变量来代替student1…的话,格式是 ‘"$Section"’,先双引号,再单引号,gsub(/[[:blank:]]*/,"",$2) 去除值两边的空格内容,printf 是格式化输出。
以上是定义的getconfig函数。

下面需要解释的是

profile=`sed -n '/ids/'p $CONFIGFILE | awk -F=  '{print $2}' | sed 's/,/ /g'`

执行符号` 表示将里面命令运行的结果赋值给变量

sed -n '/ids/'p $CONFIGFILE 

是sed命令的一种用法,表示读取文件中匹配ids的行,具体可以参考
https://www.cnblogs.com/ctaixw/p/5860221.html

 awk -F=  '{print $2}' 

用=将这一行分割,打印第二部分,即 student1,student2,student3

sed 's/,/ /g'

将逗号替换为空格
下面的内容相对简单, 主要是函数的调用方法为

 getconfig  $stdudent  $CONFIGFILE

最后的运行结果:

mk90@mk90-e420:~/Documents/myshell$ ./configOperate.sh myconfig.ini ConfigName:myconfig.ini 

--------------------------------------------------
student:student1
name		age		
LiLei		16		

--------------------------------------------------
student:student2
name		age		
HanMeiMei		15		

--------------------------------------------------
student:student3
name		age		
Lucy		15		



你可能感兴趣的:(shell)