使用shell读取ini文件方法步骤

2022-06-09 11:46:47
目录
动机.ini 类文件格式在 shell 脚本中处理 .ini 文件时要执行的操作假定处理系统查看部分列表仅提取特定部分如何限定 shell 变量名Shell scripting

动机

我决定编写一个脚本来进行干净的>

.ini>
    在 [section] 中设置节。紧接在 [和紧接之前] 之后的空白字符序列(空格 / 制表符)不被视为部分名称的一部分。 (规定可以在节名及其前后的括号之间放置空格字符。)但是,节名不应包含换行符。用 parameter = value 设置参数变量及其值。 = 前后可以有空格。假设参数名称不包括=。如果参数名称包含不能在 shell 变量中使用的字符,则在输出的 shell 变量名称中将这些字符替换为 _。如果行尾有 ,则下一行被视为续行。如果一行的开头有 4 个或更多空格/制表符,则将其视为上一行的续行。忽略 # ,; 中的行尾作为注释。忽略不包含 [and’]’ 的行,或在行首以外的位置不包含 = 的行。

    在>

    查看部分列表。

    将参数作为 shell 变量读取。 然而,作为一种变体

    1. 让特定部分的参数为 shell 变量。 在某些情况下,将其设置为 shell 函数中的局部变量或环境变量。
    2. 让所有或部分部分的参数为 shell 变量。 shell变量名是’基于段名的前缀’+‘参数名’。 同样在这种情况下,将其设置为局部变量或环境变量。 基于节名的前缀是通过将节名字符串中的shell变量中不能使用的字符替换为_并在末尾添加_来生成的。

    假定处理系统

      bashBSD>

      处理连续行和注释似乎有更普遍的用途,所以我单独描述。 通过将代码添加到那里描述的 sample5.sed 来实现上述内容。

      查看部分列表

      这相对容易。>

      :begin
      $!N
      s/[#;]([^[:space:]]|[[:blank:]])*([^\[:space:]]|[[:blank:]])(n)/3/
      s/[#;]([^[:space:]]|[[:blank:]])*(\)(n)/23/
      $s/[#;]([^[:space:]]|[[:blank:]])*$//
      /(\n|n[[:blank:]]{4})/ {
        s/[[:blank:]]*(\n|n[[:blank:]]{4})[[:blank:]]*/ /
        t begin
      }
      /^[[:blank:]]*n/ D
      /n[[:blank:]]*$/ {
        s/n[[:blank:]]*$//
        t begin
      }
      /^[([^[:space:]]|[[:blank:]])*]/! D
      s/[[[:blank:]]*//
      s/[[:blank:]]*]([^[:space:]]|[[:blank:]])*//
      P
      D

      例如,如果您尝试将其作为示例 .ini 文件,

      # -*- mode: conf-mode ; -*- 
      #;
      #; sample .ini file
      #;
      #;
      
      [tako]
      param_a=(1 # 2 3 
      4 5 ### 6 7 
          8 9 # 10
          )
      
      a=b # kani 
      # kani 
      
      
      [kani]
      param_a=1
      param_b=2
      
      [uni]
      param_a=3
      param_b=4
      
      [wani]
      param_a=5
      param_b=6
      
      [hebi]
      param_a=9
      param_b=10
      
      output example:
      
      % sed -nE -f list_section.sed sample.ini
      tako
      kani
      uni
      wani
      hebi

      仅提取特定部分

      下面的示例仅从上面的示例中提取特定部分>

      :begin
      $!N
      # Erase comment strings
      s/[#;]([^[:space:]]|[[:blank:]])*([^\[:space:]]|[[:blank:]])(n)/3/
      s/[#;]([^[:space:]]|[[:blank:]])*(\)(n)/23/
      $s/[#;]([^[:space:]]|[[:blank:]])*$//
      # Concatenate continuation lines
      /(\n|n[[:blank:]]{4})/ {
        s/[[:blank:]]*(\n|n[[:blank:]]{4})[[:blank:]]*/ /
        t begin
      }
      # Erase blank lines
      /^[[:blank:]]*n/ D
      /n[[:blank:]]*$/ {
        s/n[[:blank:]]*$//
        t begin
      }
      # Check section headline and store section name to holdspace
      /^([^[:space:]]|[[:blank:]])*[([^[:space:]]|[[:blank:]])*]/ {
      h
      x
      s/^([^[:space:]]|[[:blank:]])*[(([^[:space:]]|[[:blank:]])*)].*$/2/g
      s/^[[:blank:]]*//g
      s/[[:blank:]]$//g
      x
      D
      }
      # Skip line if current section is not interested one
      x
      /^wani$/! { 
        x
        D
      }
      x
      # Print if it is proper parameter definition 
      /^(([^[:space:]=]|[[:blank:]])*)=(([^[:space:]]|[[:blank:]])*)/ {
        s/^[[:blank:]]*/local /
        s/[[:blank:]]*=[[:blank:]]*/=/
        s/(([^[:space:]]|[[:blank:]])*)[[:blank:]]*(n)/1;3/
        P
      }
      D

      如何限定>

      如关于您想要做什么的部分中所述,您想要添加从部分名称生成的前缀到 shell 变量,或者如果 .ini 文件中的参数名称包含不能在 shell 变量中使用的字符串, 适当转换。 作为一种简单的方法,有多次调用sed并处理的方法,但是如果可以的话,我觉得用一个进程号sed就可以处理更漂亮。 这里最大的限制是 sed 没有一个保存空间。 在高级脚本语言中,可以将文本段划分为多个变量,进行存储、处理和组合。 另一方面,在 sed 的情况下,标准方法似乎是将多个文本作为堆栈保存和使用,并将保留空间作为分隔符并带有换行符。

      例如,在下面的示例中,保留空间从第一行开始。

        部分名称带格式化部分名称的前缀模式空间第一行的备份模式空间第二行的备份根据.ini文件中的参数名格式化的Shell变量名

        需要决定如何使用它,保持保持空间中的行数不变(下例中为 2 行),并在处理行转换时适当恢复模式空间。 由于交换保持空间和模式空间的命令只有gG和hH,类似的处理可能会重复出现,所以不可否认在1sed的过程中做起来真的很漂亮。

        不管怎样,下面是从上面的 sample.ini 文件中提取 wani 和 uni 部分并输出添加了部分名称的 shell 变量的定义语句的示例。 整体控制结构保持简单,并且我添加了注释,所以我希望你能看到重写的地方以提取另一个部分,例如。

        # Initialine the hold space: (Single empty line at the beginning)
        1 { H ; x ; 
          # Change the expression for the defalut section name and/or variable prefix, here.
          s/^([^[:space:]]|[[:blank:]])*(n)([^[:space:]]|[[:blank:]])*$/global2global_/g
          x
        }
        :begin
        $!N
        # Erase comment strings
        s/[#;]([^[:space:]]|[[:blank:]])*([^\[:space:]]|[[:blank:]])(n)/3/
        s/[#;]([^[:space:]]|[[:blank:]])*(\)(n)/23/
        $s/[#;]([^[:space:]]|[[:blank:]])*$//
        # Concatenate continuation lines
        /(\n|n[[:blank:]]{4})/ {
          s/[[:blank:]]*(\n|n[[:blank:]]{4})[[:blank:]]*/ / ; t begin
        }
        # Erase blank lines
        /^[[:blank:]]*n/ D
        /n[[:blank:]]*$/ {
          s/n[[:blank:]]*$// ; t begin
        }
        # Check section headline and store section name to holdspace
        /^([^[:space:]]|[[:blank:]])*[([^[:space:]]|[[:blank:]])*]/ {
          # Remove blackets and extra spaces at first line
          s/^([^[:space:]]|[[:blank:]])*[(([^[:space:]]|[[:blank:]])*)](([^[:space:]]|[[:blank:]])*)(n)/26/g
          s/^[[:blank:]]*//g; s/[[:blank:]]*(n)/1/g
          # Store the section name to the hold space, and format stored one for shell variable for the hold space
          h
          x
          s/(n)([^[:space:]]|[[:blank:]])*$//
          s/([^[:alnum:]_]|$)/_/g
          x
          # Append the section name to the hold space.
          H
          # Remove unused line of the hold space and rearrange the remaining lines.
          x
          s/(([^[:space:]]|[[:blank:]])*)(n)(([^[:space:]]|[[:blank:]])*)(n)(([^[:space:]]|[[:blank:]])*)$/431/
          x
          D
        }
        # Skip line if current section is not interested one
        x
        /^(wani|uni)(n)/! { x ; D ; }
        x
        # Print if it is proper parameter definition 
        /^(([^[:space:]=]|[[:blank:]])*)=(([^[:space:]]|[[:blank:]])*)/ {
          # Store current patern space text at the end of the hold space
          H
        
          # Build shell script variable name and store it at the end of the hold space
          s/(([^[:space:]=]|[[:blank:]])*)=.*$/1/g
          s/^[[:blank:]]*//
          s/[[:blank:]]*$//
          s/[^[:alnum:]_]/_/g
          # If further rename of the variable name is necessary, put here.
        
          # Store variable name at the end of the hold space
          H
        
          # Build parameter variable value and keep it at pattern space
          # At first, Resore the current line text from hold space
          g
          # Remove unused lines.
          s/^(([^[:space:]]|[[:blank:]])*n){2}//
          s/(n([^[:space:]]|[[:blank:]])*){2}$//
          # Remove the text other than the parameter value
          s/^([^[:space:]=]|[[:blank:]])*=//g
          # If further formatting of the value is necessary, put here.
        
          # Append hold space stored date into pattern space
          G
          # Remove unused lines from the pattern space
          s/^(([^[:space:]]|[[:blank:]])*n)(([^[:space:]]|[[:blank:]])*n)(([^[:space:]]|[[:blank:]])*n)(([^[:space:]]|[[:blank:]])*n)(([^[:space:]]|[[:blank:]])*n)/159/
          # Rearrance the order of line in the pattern space, it is nessacery because only 1 ...9 is avaiable
          s/^(([^[:space:]]|[[:blank:]])*n)(([^[:space:]]|[[:blank:]])*n)(([^[:space:]]|[[:blank:]])*)(n)(([^[:space:]]|[[:blank:]])*)$/13875/
        
          # Format the output in the first line of the pattern space, and 
          # Restore the next line at the second line of the pattern space
          s/^(([^[:space:]]|[[:blank:]])*)(n)(([^[:space:]]|[[:blank:]])*)(n)(([^[:space:]]|[[:blank:]])*)(n([^[:space:]]|[[:blank:]])*)$/local 47=1;9/
        
          # Clean up hold space
          x
          s/(n([^[:space:]]|[[:blank:]])*){3}$//
          x
          P
        }
        D

        output example:

        % sed -n -E -f pickup_section2.sed sample.ini
        local uni_param_a=3;
        local uni_param_b=4;
        local wani_param_a=5;
        local wani_param_b=6;

        Shell>

        每次更改要提取的section或者切换输出格式(sh/csh、shell变量/局部变量/环境变量、变量名前缀的ON/OFF)都要重写sed文件很麻烦,所以命令行我准备了生成 sed 命令作为选项的 shell 脚本。 使用另一篇文章中的模板生成。 对于上面的seds,我还尝试了通过.ini文件的参数变量名(shell变量名)来选择输出。 (但是,如果指定了多个段名和变量名,组合不是唯一的,所以它可能不是一个很有用的功能。)

        文件存储:

        https://github.com/nanigashi-uji/parse_ini_sh
        https://gitlab.com/nanigashi_uji/parse_ini_sh

        如何使用

        [Usage] % parse_ini.sh -list     file [files ...]
                % parse_ini.sh [options] file [files ...]
        
        [Options]
            -l,--list                       : List sections 
            -S,--sec-select       name      : Section name to select
            -T,--sec-select-regex expr      : Section reg. expr. to select
            -V,--variable-select name       : variable name to select
            -W,--variable-select-regex expr : variable reg. expr. to select
            -L,--local                      : Definition as local variables (B-sh)
            -e,--env                        : Definition as enviromnental variables
            -q,--quot                       : Definition by quoting with double/single-quotation.
            -c,--csh,--tcsh                 : Output for csh statement (default: B-sh)
            -b,--bsh,--bash                 : Output for csh statement (default)
            -s,--sec-prefix                 : add prefix: 'sectionname_' to variable names. 
            -v,--verbose                    : Verbose messages 
            -h,--help                       : Show Help (this message)

        output example:

        % parse_ini.sh --list sample.ini
        tako
        kani
        uni
        wani
        hebi

        % parse_ini.sh -S kani -L sample.ini
        local param_a=1;
        local param_b=2;

        % parse_ini.sh -S kani -L -s sample.ini
        local kani_param_a=1;
        local kani_param_b=2;

        % parse_ini.sh -S kani -L -e -c sample.ini
        setenv param_a 1;
        setenv param_b 2;

        % parse_ini.sh -S kani -L -e -c -q sample.ini
        setenv param_a "1";
        setenv param_b "2";

         到此这篇关于使用shell读取ini文件方法步骤的文章就介绍到这了,更多相关shell读取ini文件内容请搜索易采站长站以前的文章或继续浏览下面的相关文章希望大家以后多多支持易采站长站!