在bash脚本中从ini文件中读取属性

时间:2017-05-12 07:08:15

标签: bash shell unix

我是shell脚本的新手,我需要使用示例示例解释。我有一个属性文件,其中包含如下所示的数据:

object1 : propertyA

object2 : property1 property2

object3 : propertyxyz

注意:总的来说,我有一些可以拥有任意数量属性的对象。我需要将其保存在属性文件中,以便可以根据需要进行更改。

我只需要将对象3作为用户输入,那么我的代码应该打印所有相应的属性。

我尝试过使用.ini文件,但我不想使用任何外部解析器。在这种情况下,bash似乎没有帮助我。如果我使用grep,那么我将不得不使用一些正则表达式来拆分属性。

我创建的

.ini文件:

[object1]

property=propertyA


[object2]

property=property1

property=property2

[object3]

property=propertyxya

我正在寻找一种解决方案,如果我选择一个对象(在ini文件的情况下它是一个部分),那么我应该得到一个数组中的所有属性。

那么有没有在bash中预定义的东西,或者我只需要使用grep n regex编写。

5 个答案:

答案 0 :(得分:2)

可以使用Awk轻松完成漂亮,只需执行以下操作即可将内容存储在bash数组中。

read -p "Enter object to get properties for: " objectname
all_properties=($(awk -F '=' -v input="${objectname}" '$1 ~ input{flag=1; next} $1 ~ /\[object/{flag=0; next} flag && NF {split($0,arr,"="); print arr[2] }  config.ini))

现在循环数组以打印属性

for property in "${all_properties[@]}"; do
    printf "%s\n" "$property"
done

(或)只是

printf "%s\n" "${all_properties[@]}"

Awk命令的工作原理如下: -

  1. 在变量中获取用户输入并使用Awk语法传递给-v并执行正则表达式匹配$1 ~ input以匹配包含用户输入的行,例如object1
  2. 我启用一个标志,开始在此行上标记行,并在下一个对象启动后重置标志,请参阅$1 ~ /\[object/{flag=0; next}
  3. 条件flag && NF负责处理非空行,仅处理请求对象后的属性值。
  4. 现在在选定的行上,使用split()中的Awk函数,我们可以提取属性的值并将其打印出来,稍后将存储在数组中。
  5. read和下面一行放在bash脚本中,并将she-bang设置为#!/bin/bash并运行。

    E.g。在一个完整的脚本

    #!/usr/bin/bash
    read -p "Enter object to get properties for: " objectname
    all_properties=($(awk -F '=' -v input="${objectname}" '$1 ~ input{flag=1; next} $1 ~ /\[object/{flag=0; next} flag && NF {split($0,arr,"="); print arr[2] }' config.ini ))
    
    printf "%s\n" "${all_properties[@]}"
    

    脚本上运行了一些示例。

    $ bash script.sh
    Enter object to get properties for: object1
    propertyA
    
    $ bash script.sh
    Enter object to get properties for: object2
    property1
    property2
    
    $ bash script.sh
    Enter object to get properties for: object3
    propertyxya
    

答案 1 :(得分:0)

使用awk我们可以为[object]行创建一个正则表达式,我们只是捕获它。然后我们有一个property=行的正则表达式,在这里,我们将对象加入到属性中:

awk '
/^\[[a-z0-9]*\]$/ { obj=$0 }
/^property=.*/ { print obj $0 }
' filename.ini

产生中间输出:

[object1]property=propertyA
[object2]property=property1
[object2]property=property2
[object3]property=propertyxya

然后,为了获取[object2]的属性,我们只使用grepsed

obj=object2
result=$(echo $(awk '
/^\[[a-z0-9]*\]$/ { obj=$0 }
/^property=.*/ { print obj $0 }
' filename.ini | grep '^\['$obj'\]' | sed 's/.*property=//'))

这会产生:

result=property1 property2

答案 2 :(得分:0)

我会做这样的事情,其中​​XXXXXXX是对象名称:

awk '/\[XXXXXXX\]/{flag=1;next}/\[.*\]/{flag=0}flag && NF' test.ini

例如:

awk '/\[object1\]/{flag=1;next}/\[.*\]/{flag=0}flag && NF' test.ini
property=propertyA

awk '/\[object2\]/{flag=1;next}/\[.*\]/{flag=0}flag && NF' test.ini
property=property1
property=property2

awk '/\[object3\]/{flag=1;next}/\[.*\]/{flag=0}flag && NF' test.ini
property=propertyxya

有关详细信息,请参阅此帖子:How to select lines between two patterns?

对于数组中的格式,它将取决于数组的外观

答案 3 :(得分:0)

有一个项目提供了解析ini文件的功能:bash_ini_parser

它只需要bash,不需要其他工具。

答案 4 :(得分:0)

尽管此回复晚了 4 年,但只是将其放在这里供任何寻找更清洁实用程序的人使用。 查看 Rudiger Meier 的 simple ini parser

curl -SSL https://raw.githubusercontent.com/rudimeier/bash_ini_parser/master/read_ini.sh > $HOME/bin/read_ini.sh

使用上面的 curl 来获取脚本。

USAGE
-----

You must source the bash file into your script:

> . read_ini.sh

and then use the read_ini function, defined as:

> read_ini INI_FILE [SECTION] [[--prefix|-p] PREFIX] [[--booleans|b] [0|1]]

If SECTION is supplied, then only the specified section of the file will
be processed.

After running the read_ini function, variables corresponding to the ini
file entries will be available to you. Naming convention for variable
names is:

PREFIX__SECTION__VARNAME

PREFIX is 'INI' by default (but can be changed with the --prefix option),
SECTION and VARNAME are the section name and variable name respectively.

Additionally you can get a list of all these variable names:
PREFIX__ALL_VARS
and get a list of sections:
PREFIX__ALL_SECTIONS
and the number of sections:
PREFIX__NUMSECTIONS