【问题标题】:Read certain key from certain section of ini file (sed/awk ?)从 ini 文件的某些部分读取某些键(sed/awk?)
【发布时间】:2014-04-28 07:39:19
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: file sed awk ini


    【解决方案1】:

    这可能是一个开始:

    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

    [efgh] 部分下查找key1 的值:

    $ 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
    

    [hijk] 部分下查找key2 的值:

    $ 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
    

    【讨论】:

    • @Michelle 你能详细说明什么不起作用吗?错误?什么都没找到?在您的问题中发布相关数据集。这只是打印值。你想要整个key=value 对吗?
    【解决方案2】:

    使用 sed

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

    另一种方式

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

    【讨论】:

    • 像这样吞食整个文件可能不是一个好主意。
    • 好建议,第二个怎么样?我是根据@Guru 的想法制作的。
    • 抱怨 Perl 不可读的人应该尝试 sed ... :-)。但是,第二个示例中的反斜杠迷宫完美地满足了我的要求!
    【解决方案3】:

    一种方式:

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

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

    【讨论】:

    • 你实际上可以通过 sed -nr '/\[efgh\]/,/\[.*\]/{/key1/s/(.*)=(.*)/\2/p}' file 避免 awk
    【解决方案4】:

    这些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
    

    【讨论】:

      【解决方案5】:

      这可能对你有用(GNU sed):

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

      复制节标题并将其与节正文进行比较。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-02
        • 1970-01-01
        • 1970-01-01
        • 2011-04-13
        • 2016-10-18
        • 1970-01-01
        相关资源
        最近更新 更多