bash 如何在 shell 脚本中获取 INI 值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6318809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I grab an INI value within a shell script?
提问by Stephen Watkins
I have a parameters.ini file, such as:
我有一个parameters.ini文件,比如:
[parameters.ini]
database_user = user
database_version = 20110611142248
I want to read in and use the database version specified in the parameters.ini file from within a bash shell script so I can process it.
我想从 bash shell 脚本中读入并使用 parameters.ini 文件中指定的数据库版本,以便我可以处理它。
#!/bin/sh
# Need to get database version from parameters.ini file to use in script
php app/console doctrine:migrations:migrate $DATABASE_VERSION
How would I do this?
我该怎么做?
采纳答案by Ali Lown
How about grepping for that line then using awk
如何grepping该行然后使用awk
version=$(awk -F "=" '/database_version/ {print }' parameters.ini)
回答by kenorb
You can use bash native parser to interpret ini values, by:
您可以使用 bash 本机解析器来解释 ini 值,方法是:
$ source <(grep = file.ini)
Sample file:
示例文件:
[section-a]
var1=value1
var2=value2
IPS=( "1.2.3.4" "1.2.3.5" )
To access variables, you simply printing them: echo $var1
. You may also use arrays as shown above (echo ${IPS[@]}
).
要访问变量,您只需打印它们:echo $var1
. 您也可以使用如上所示的数组 ( echo ${IPS[@]}
)。
If you only want a single value just grep for it:
如果您只想要一个值,只需 grep 即可:
source <(grep var1 file.ini)
For the demo, check this recording at asciinema.
对于演示,请在 asciinema 检查此录音。
It is simple as you don't need for any external library to parse the data, but it comes with some disadvantages. For example:
这很简单,因为您不需要任何外部库来解析数据,但它有一些缺点。例如:
If you have spaces between
=
(variable name and value), then you've to trim the spaces first, e.g.$ source <(grep = file.ini | sed 's/ *= */=/g')
Or if you don't care about the spaces (including in the middle), use:
$ source <(grep = file.ini | tr -d ' ')
To support
;
comments, replace them with#
:$ sed "s/;/#/g" foo.ini | source /dev/stdin
The sections aren't supported (e.g. if you've
[section-name]
, then you've to filter it out as shown above, e.g.grep =
), the same for other unexpected errors.If you need to read specific value under specific section, use
grep -A
,sed
,awk
orex
).E.g.
source <(grep = <(grep -A5 '\[section-b\]' file.ini))
Note: Where
-A5
is the number of rows to read in the section. Replacesource
withcat
to debug.If you've got any parsing errors, ignore them by adding:
2>/dev/null
如果
=
(变量名和值)之间有空格,则必须先修剪空格,例如$ source <(grep = file.ini | sed 's/ *= */=/g')
或者,如果您不关心空格(包括中间),请使用:
$ source <(grep = file.ini | tr -d ' ')
要支持
;
评论,请将其替换为#
:$ sed "s/;/#/g" foo.ini | source /dev/stdin
不支持这些部分(例如,如果您有
[section-name]
,那么您必须如上所示将其过滤掉,例如grep =
),对于其他意外错误也是如此。如果您需要读取特定部分下的特定值,请使用
grep -A
、sed
、awk
或ex
)。例如
source <(grep = <(grep -A5 '\[section-b\]' file.ini))
注意:
-A5
节中要读取的行数在哪里。替换source
与cat
调试。如果您有任何解析错误,请通过添加以下内容忽略它们:
2>/dev/null
See also: How to parse and convert ini file into bash array variables?at serverfault SE
另请参阅:如何解析 ini 文件并将其转换为 bash 数组变量?在服务器故障 SE
回答by Fredrik Pihl
Bash does not provide a parser for these files. Obviously you can use an awk command or a couple of sed calls, but if you are bash-priest and don't want to use any other shell, then you can try the following obscure code:
Bash 没有为这些文件提供解析器。显然您可以使用 awk 命令或几个 sed 调用,但如果您是 bash-priest 并且不想使用任何其他 shell,那么您可以尝试以下晦涩的代码:
#!/usr/bin/env bash
cfg_parser ()
{
ini="$(<)" # read the file
ini="${ini//[/\[}" # escape [
ini="${ini//]/\]}" # escape ]
IFS=$'\n' && ini=( ${ini} ) # convert to line-array
ini=( ${ini[*]//;*/} ) # remove comments with ;
ini=( ${ini[*]/\ =/=} ) # remove tabs before =
ini=( ${ini[*]/=\ /=} ) # remove tabs after =
ini=( ${ini[*]/\ =\ /=} ) # remove anything with a space around =
ini=( ${ini[*]/#\[/\}$'\n'cfg.section.} ) # set section prefix
ini=( ${ini[*]/%\]/ \(} ) # convert text2function (1)
ini=( ${ini[*]/=/=\( } ) # convert item to array
ini=( ${ini[*]/%/ \)} ) # close array parenthesis
ini=( ${ini[*]/%\ \)/ \} ) # the multiline trick
ini=( ${ini[*]/%\( \)/\(\) \{} ) # convert text2function (2)
ini=( ${ini[*]/%\} \)/\}} ) # remove extra parenthesis
ini[0]="" # remove first element
ini[${#ini[*]} + 1]='}' # add the last brace
eval "$(echo "${ini[*]}")" # eval the result
}
cfg_writer ()
{
IFS=' '$'\n'
fun="$(declare -F)"
fun="${fun//declare -f/}"
for f in $fun; do
[ "${f#cfg.section}" == "${f}" ] && continue
item="$(declare -f ${f})"
item="${item##*\{}"
item="${item%\}}"
item="${item//=*;/}"
vars="${item//=*/}"
eval $f
echo "[${f#cfg.section.}]"
for var in $vars; do
echo $var=\"${!var}\"
done
done
}
Usage:
用法:
# parse the config file called 'myfile.ini', with the following
# contents::
# [sec2]
# var2='something'
cfg.parser 'myfile.ini'
# enable section called 'sec2' (in the file [sec2]) for reading
cfg.section.sec2
# read the content of the variable called 'var2' (in the file
# var2=XXX). If your var2 is an array, then you can use
# ${var[index]}
echo "$var2"
Bash ini-parser can be found at The Old School DevOps blog site.
Bash ini-parser 可以在The Old School DevOps 博客站点上找到。
回答by egridasov
Sed one-liner, that takes sections into account. Example file:
Sed one-liner,将部分考虑在内。示例文件:
[section1]
param1=123
param2=345
param3=678
[section2]
param1=abc
param2=def
param3=ghi
[section3]
param1=000
param2=111
param3=222
Say you want param2 from section2. Run the following:
假设您想要第 2 节中的 param2。运行以下命令:
sed -nr "/^\[section2\]/ { :l /^param2[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}" ./file.ini
will give you
会给你
def
回答by Gustavo González
Just include your .ini file into bash body:
只需将您的 .ini 文件包含到 bash 正文中:
File example.ini:
文件example.ini:
DBNAME=test
DBUSER=scott
DBPASSWORD=tiger
File example.sh
文件example.sh
#!/bin/bash
#Including .ini file
. example.ini
#Test
echo "${DBNAME} ${DBUSER} ${DBPASSWORD}"
回答by Opux
All of the solutions I've seen so far also hit on commented out lines. This one didn't, if the comment code is ;
:
到目前为止,我看到的所有解决方案也都出现在注释掉的行上。这个没有,如果评论代码是;
:
awk -F '=' '{if (! (dbver=$(sed -n 's/.*database_version *= *\([^ ]*.*\)//p' < parameters.ini)
echo $dbver
~ /^;/) && sed -n -e 's/^\s*my_key\s*=\s*//p' my_file
~ /database_version/) print }' file.ini
回答by jm666
one of more possible solutions
更多可能的解决方案之一
$ cat my_file
# Example INI file
something = foo
my_key = bar
not_my_key = baz
my_key_2 = bing
$ sed -n -e 's/^\s*my_key\s*=\s*//p' my_file
bar
回答by Dean Rather
Display the value of my_keyin an ini-style my_file:
在 ini 样式的my_file 中显示my_key的值:
# last modified 1 April 2001 by John Doe
[owner]
name=John Doe
organization=Acme Widgets Inc.
[database]
# use IP address in case network name resolution is not working
server=192.0.2.62
port=143
file=payroll.dat
-n
-- do not print anything by default-e
-- execute the expressions/PATTERN//p
-- display anything following this pattern In the pattern:^
-- pattern begins at the beginning of the line\s
-- whitespace character*
-- zero or many (whitespace characters)
-n
-- 默认不打印任何内容-e
-- 执行表达式s/PATTERN//p
-- 显示任何遵循此模式的内容 在模式中:^
-- 模式从行首开始\s
-- 空白字符*
-- 零个或多个(空白字符)
Example:
例子:
# Configuration bindings found outside any section are given to
# to the default section.
1 {
x
s/^/default/
x
}
# Lines starting with a #-character are comments.
/#/n
# Sections are unpacked and stored in the hold space.
/\[/ {
s/\[\(.*\)\]//
x
b
}
# Bindings are unpacked and decorated with the section
# they belong to, before being printed.
/=/ {
s/^[[:space:]]*//
s/[[:space:]]*=[[:space:]]*/|/
G
s/\(.*\)\n\(.*\)/|/
p
}
So:
所以:
Find a pattern where the line begins with zero or many whitespace characters, followed by the string my_key, followed by zero or many whitespace characters, an equal sign, then zero or many whitespace characters again. Display the rest of the content on that line following that pattern.
找到一个模式,其中该行以零个或多个空白字符开头,后跟字符串my_key,然后是零个或多个空白字符,一个等号,然后又是零个或多个空白字符。按照该模式显示该行上的其余内容。
回答by kenorb
sed
sed
You can use sed
to parse the ini configuration file, especially when you've section names like:
您可以使用sed
来解析 ini 配置文件,尤其是当您有像这样的部分名称时:
owner|name|John Doe
owner|organization|Acme Widgets Inc.
database|server|192.0.2.62
database|port|143
database|file|payroll.dat
so you can use the following sed
script to parse above data:
所以你可以使用下面的sed
脚本来解析上面的数据:
this will convert the ini data into this flat format:
这会将 ini 数据转换为这种平面格式:
##代码##so it'll be easier to parse using sed
, awk
or read
by having section names in every line.
所以它会更容易使用解析sed
,awk
或者read
通过在每行有节的名称。
Credits & source: Configuration files for shell scripts, Michael Grünewald
积分和来源:shell 脚本的配置文件,Michael Grünewald
Alternatively, you can use this project: chilladx/config-parser
, a configuration parser using sed
.
或者,您可以使用这个项目:chilladx/config-parser
,一个使用sed
.
回答by wally
For people (like me) looking to read INI files from shell scripts (read shell, not bash) - I've knocked up the a little helper library which tries to do exactly that:
对于希望从 shell 脚本(读取 shell,而不是 bash)读取 INI 文件的人(像我一样) - 我已经敲了一个小助手库,它试图做到这一点:
https://github.com/wallyhall/shini(MIT license, do with it as you please. I've linked above including it inline as the code is quite lengthy.)
https://github.com/wallyhall/shini(MIT许可证,请随意使用它。我已经在上面链接了它,因为代码很长。)
It's somewhat more "complicated" than the simple sed
lines suggested above - but works on a very similar basis.
它比sed
上面建议的简单线条更“复杂” - 但工作原理非常相似。
Function reads in a file line-by-line - looking for section markers ([section]
) and key/value declarations (key=value
).
函数逐行读取文件 - 查找部分标记 ( [section]
) 和键/值声明 ( key=value
)。
Ultimately you get a callback to your own function - section, key and value.
最终你会得到一个你自己的函数的回调——部分、键和值。