免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6969 | 回复: 12
打印 上一主题 下一主题

shell读取配置文件方式[未解决] [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-06-01 21:32 |只看该作者 |倒序浏览
本帖最后由 ajiankk 于 2010-06-01 22:26 编辑

我现在想做一个读配置文件的脚本
其实想模仿大部分的linux软件的配置文件方式
如rsyncd.conf php.ini的配置

类似如下的配置文件
error log=/tmp/rsyncd.log
[test]
path = /data0/www/
hosts allow = 10.0.0.0/255.0.0.0
hosts deny = *
list = true
uid = www
gid = www
read only = no

现在的问题是:
怎么去匹配[test]这个段里面的参数  
其实最后问题思路就是:如何匹配显示[test]到下一个[ ]之间内容
情况又有三种:
1)在所有[] 之前的为全局配置文件
2) 匹配显示两个[] 之间的内容
3)匹配最后一个[] 的内容

想最后脚本的使用方式就是 ./shell1.sh -m "test"   (test即配置文件的区域)

不知道有没有描述清楚,是否有人可以帮下。先谢谢。

论坛徽章:
0
2 [报告]
发表于 2010-06-01 22:12 |只看该作者
找到方法了 使用 awk 的F 和RS
  1. awk -F[ 'BEGIN{RS = ""} /test]/' a.txt
复制代码

论坛徽章:
0
3 [报告]
发表于 2010-06-01 22:29 |只看该作者
有个小问题
如果用上面的方法
必需要配置文件[]区域之间用空格分开

但是如果使用
awk -F[ 'BEGIN{RS = "["} /test]/' a.txt
又会缺少一个[

test]
path = /home/server
hosts allow = 10.0.0.0/255.0.0.0
hosts deny = *
list = true
uid = root
gid = root
read only = no

其实我只需要
path = /home/server
hosts allow = 10.0.0.0/255.0.0.0
hosts deny = *
list = true
uid = root
gid = root
read only = no
这部分内容

另外有个怀疑是
awk -F[ 'BEGIN{RS = "["} /test]/'  里面的test是否可以用变量代替

论坛徽章:
0
4 [报告]
发表于 2010-06-01 23:09 |只看该作者
查到一个脚本 可以解决 但脚本整个测试是有问题的 如newvalue 参数 不过可以拿下部分出来使用。
  1. #!/bin/sh
  2. if [ $# -lt 2 ];then
  3. echo 'Usage:inifile <.ini file> <section> [<key>] [<newvalue>]'
  4. exit 1
  5. fi
  6. if [ "$3" = "" ];then
  7.    sed -n "/\[$2\]/,/\[.*\]/{
  8.    /^\[.*\]/d
  9.    /^[ ]*$/d
  10.    s/;.*$//
  11.    p
  12.    }" $1
  13. elif [ "$4" = "" ];then
  14.    sed -n "/\[$2\]/,/\[.*\]/{
  15.    /^\[.*\]/d
  16.    /^[ ]*$/d
  17.    s/;.*$//
  18.    s/^[ |        ]*$3[ | ]*=[ |   ]*\(.*\)[ |     ]*/\1/p
  19.    }" $1
  20. else
  21.        if [ "$4" = "#" ];then
  22.             sed "/\[$2\]/,/\[.*\]/{
  23.             s/^[ |        ]*$3[ |    ]*=.*/ /
  24.             }p" $1 > /tmp/sed$
  25.             mv /tmp/sed$ $1
  26.        else
  27.             sed "/\[$2\]/,/\[.*\]/{
  28.             s/^[ |        ]*$3[ |    ]*=.*/$3=$4/
  29.             }p" $1 > /tmp/sed$
  30.             mv /tmp/sed$ $1
  31.        fi
  32. fi
复制代码

论坛徽章:
0
5 [报告]
发表于 2010-06-01 23:31 |只看该作者
自己动手,丰衣足食

论坛徽章:
0
6 [报告]
发表于 2010-06-02 00:23 |只看该作者
这个意思?
  1. [root@Mylinux tmp]# cat file
  2. error log=/tmp/rsyncd.log
  3. [test]
  4. path = /data0/www/
  5. hosts allow = 10.0.0.0/255.0.0.0
  6. hosts deny = *
  7. list = true
  8. uid = www
  9. gid = www
  10. read only = no

  11. [test1]
  12. aa
  13. bb
  14. [root@Mylinux tmp]# awk -v key="test" -v RS='\\[[^\n]*]' 'v=="["key"]";{v=RT}' file

  15. path = /data0/www/
  16. hosts allow = 10.0.0.0/255.0.0.0
  17. hosts deny = *
  18. list = true
  19. uid = www
  20. gid = www
  21. read only = no


  22. [root@Mylinux tmp]# awk -v key="test1" -v RS='\\[[^\n]*]' 'v=="["key"]";{v=RT}' file

  23. aa
  24. bb

  25. [root@Mylinux tmp]#
复制代码

论坛徽章:
0
7 [报告]
发表于 2010-06-02 02:09 |只看该作者
本帖最后由 ajiankk 于 2010-06-02 02:58 编辑

回复 6# ywlscpl


    嗯 想得到这样的结果 可能实际还会有更多的判断处理

    其实最终目的还是需要调用这个区域内的变量

     我只想到了一个简单方法就是
     把过虑出来的内容导入到 一个新的文件中如 /tmp/.section.ini
     再在脚本中进行调用
     . /tmp/.section.ini
这样这个区域的变量就可以直接调用了

    不知道有没有其它的方法,可以不需要导出到一个过渡文件。

论坛徽章:
0
8 [报告]
发表于 2010-06-02 10:35 |只看该作者
本帖最后由 ajiankk 于 2010-06-02 10:36 编辑

发现一个比较有趣的分析ini的bash脚本
  1. Found an interesting short script that parses INI files, for some discussion and improvements see 1
  2. cfg.parser () {
  3.     IFS=\n' && ini=( $(<$1) )              # convert to line-array
  4.     ini=( ${ini[*]//;*/} )                   # remove comments
  5.     ini=( ${ini[*]/#[/\}\n'cfg.section.} ) # set section prefix
  6.     ini=( ${ini[*]/%]/ \(} )                 # convert text2function (1)
  7.     ini=( ${ini[*]/=/=\( } )                 # convert item to array
  8.     ini=( ${ini[*]/%/ \)} )                  # close array parenthesis
  9.     ini=( ${ini[*]/%\( \)/\(\) \{} )         # convert text2function (2)
  10.     ini=( ${ini[*]/%\} \)/\}} )              # remove extra parenthesis
  11.     ini[0]=''                                # remove first element
  12.     ini[${#ini[*]} + 1]='}'                  # add the last brace
  13.     eval "$(echo "${ini[*]}")"               # eval the result
  14. }
  15. Usage:
  16. # parse the config file called 'myfile.ini', with the following
  17. # contents::
  18. #   [sec2]
  19. #   var2='something'
  20. cfg.parser 'myfile.ini'

  21. # enable section called 'sec2' (in the file [sec2]) for reading
  22. cfg.section.sec2

  23. # read the content of the variable called 'var2' (in the file
  24. # var2=XXX). If your var2 is an array, then you can use
  25. # ${var[index]}
  26. echo "$var2"
复制代码

论坛徽章:
0
9 [报告]
发表于 2010-06-02 14:25 |只看该作者
最后发现还是需要一个格式化ini的函数

因为如果ini文件不按严格的格式来写的话
如=号前后不能有空格

那么将读不到这个变量

所以现在的问题是 :如果去除=号前后的空格

还在查,有谁可以直接告诉我

如:
[test]
#commnet
ip           = '1.1.1.1  1.1.2.3'
module  =  abc
path      =  /home/server


需要格式化为
[test]
ip='1.1.1.1  1.1.2.3'
module=abc
path=/home/server

论坛徽章:
0
10 [报告]
发表于 2010-06-02 16:56 |只看该作者
http://salogs.com/2010/04/shell% ... %E6%8A%80%E5%B7%A7/

这篇文章的第12条看看能否解决你的问题。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP