我是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编写。
答案 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
命令的工作原理如下: -
Awk
语法传递给-v
并执行正则表达式匹配$1 ~ input
以匹配包含用户输入的行,例如object1
$1 ~ /\[object/{flag=0; next}
flag && NF
负责处理非空行,仅处理请求对象后的属性值。split()
中的Awk
函数,我们可以提取属性的值并将其打印出来,稍后将存储在数组中。将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]的属性,我们只使用grep
和sed
:
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