从ini文件的某些部分读取某些密钥(sed / awk?)

时间:2014-03-21 04:37:01

标签: file sed awk ini

我需要从具有典型结构的ini文件中检索键的值:

[abcd]
key1=a
key2=b
[efgh]
key1=c
key2=d
[hijk]
key1=e
key2=f

在不同的部分重复使用键名,并且没有一致的命名/部分顺序。我怎么能从efgh找到key1?如果我grep然后我将找到所有key1(并且我不知道这些部分的顺序)。

我怀疑sed或awk可以做到这一点,但我找不到它......

5 个答案:

答案 0 :(得分:3)

这可能是一个开始:

awk -F'=' -v section="[efgh]" -v k="key1"  '
$0==section{ f=1; next }  # Enable a flag when the line is like your section
/\[/{ f=0; next }         # For any lines with [ disable the flag
f && $1==k{ print $0 }    # If flag is set and first field is the key print key=value
' ini.file

您传递了两个变量,sectionksection需要包含您要查看的部分。 k应包含您尝试获取价值的key

key1部分找到[efgh]的值:

$ awk -F'=' -v section="[efgh]" -v k="key1"  '
$0==section{ f=1; next }  
/\[/{ f=0; next }         
f && $1==k{ print $0 }      
' ini.file
key1=c

key2部分找到[hijk]的值:

$ awk -F'=' -v section="[hijk]" -v k="key2"  '
$0==section{ f=1; next }  
/\[/{ f=0; next }         
f && $1==k{ print $0 }      
' ini.file
key2=f

答案 1 :(得分:3)

使用sed

sed -r ':a;$!{N;ba};s/.*\[efgh\][^[]*(key1=[^\n]*).*/\1/' file

key1=c

另一种方式

sed -nr '/\[efgh\]/,/\[/{/key1/p}' file

答案 2 :(得分:2)

一种方式:

sed -n '/\[efgh\]/,/\[.*\]/p' file | awk -F= '/key2/{print $2}'

使用sed,从[efgh]到下一个[....]模式中提取行范围。使用awk,在此行范围内搜索key2并获取值。

答案 3 :(得分:0)

这可能适合你(GNU sed):

sed -rn '/^\[/{h;d};G;s/^key1=(.*)\n\[efgh\]$/\1/p' file

复制节标题并将其与节主体进行比较。

答案 4 :(得分:0)

这些sed单线为我工作,是从github:thomedes/ini.sed中无耻复制的

#  List all [sections] of a .INI file
sed -n 's/^[ \t]*\[\(.*\)\].*/\1/p'

#  Read KEY from [SECTION]
sed -n '/^[ \t]*\[SECTION\]/,/\[/s/^[ \t]*KEY[ \t]*=[ \t]*//p'

#  Read all values from SECTION in a clean KEY=VALUE form
sed -n '/^[ \t]*\[SECTION\]/,/\[/s/^[ \t]*\([^#; \t][^ \t=]*\).*=[ \t]*\(.*\)/\1=\2/p'

# examples:
sed -n 's/^[ \t]*\[\(.*\)\].*/\1/p' /etc/samba/smb.conf
sed -n '/^[ \t]*\[global\]/,/\[/s/^[ \t]*workgroup[ \t]*=[ \t]*//p' /etc/samba/smb.conf
sed -n '/^[ \t]*\[global\]/,/\[/s/^[ \t]*\([^#; \t][^ \t=]*\).*=[ \t]*\(.*\)/\1=\2/p' /etc/samba/smb.conf