在 bash 中解析 .ini 文件

Ras*_*Ras 6 bash ini

我有一个下面的属性文件,并想如下所述解析它。请帮忙做这件事。

我创建的 .ini 文件:

[Machine1]

app=version1


[Machine2]

app=version1

app=version2

[Machine3]

app=version1
app=version3
Run Code Online (Sandbox Code Playgroud)

我正在寻找一个解决方案,其中应该像解析 ini 文件一样

[Machine1]app = version1
[Machine2]app = version1
[Machine2]app = version2
[Machine3]app = version1
[Machine3]app = version3
Run Code Online (Sandbox Code Playgroud)

谢谢。

Joh*_*024 9

尝试:

$ awk '/\[/{prefix=$0; next} $1{print prefix $0}' file.ini
[Machine1]app=version1
[Machine2]app=version1
[Machine2]app=version2
[Machine3]app=version1
[Machine3]app=version3
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

  • /\[/{prefix=$0; next}

    如果任何行以 开头[,我们将该行保存在变量中prefix,然后我们跳过其余的命令并跳转到该next行。

  • $1{print prefix $0}

    如果当前行不为空,我们打印前缀,后跟当前行。

添加空格

在任何出现的 周围添加空格=

$ awk -F= '/\[/{prefix=$0; next} $1{$1=$1; print prefix $0}' OFS=' = ' file.ini
[Machine1]app = version1
[Machine2]app = version1
[Machine2]app = version2
[Machine3]app = version1
[Machine3]app = version3
Run Code Online (Sandbox Code Playgroud)

这通过=用作输入=的字段分隔符和输出的字段分隔符来工作。


dav*_*ive 7

我喜欢@John1024 的回答。我正是在寻找那个。我创建了一个 bash 函数,它允许我根据他的想法查找部分或特定键:

function iniget() {
  if [[ $# -lt 2 || ! -f $1 ]]; then
    echo "usage: iniget <file> [--list|<section> [key]]"
    return 1
  fi
  local inifile=$1

  if [ "$2" == "--list" ]; then
    for section in $(cat $inifile | grep "\[" | sed -e "s#\[##g" | sed -e "s#\]##g"); do
      echo $section
    done
    return 0
  fi

  local section=$2
  local key
  [ $# -eq 3 ] && key=$3

  # /sf/ask/3457998911/
  # This awk line turns ini sections => [section-name]key=value
  local lines=$(awk '/\[/{prefix=$0; next} $1{print prefix $0}' $inifile)
  for line in $lines; do
    if [[ "$line" = \[$section\]* ]]; then
      local keyval=$(echo $line | sed -e "s/^\[$section\]//")
      if [[ -z "$key" ]]; then
        echo $keyval
      else          
        if [[ "$keyval" = $key=* ]]; then
          echo $(echo $keyval | sed -e "s/^$key=//")
        fi
      fi
    fi
  done
}
Run Code Online (Sandbox Code Playgroud)

所以把它作为 file.ini

[Machine1]
app=version1
[Machine2]
app=version1
app=version2
[Machine3]
app=version1
app=version3
Run Code Online (Sandbox Code Playgroud)

然后产生以下结果

$ iniget file.ini --list
Machine1
Machine2
Machine3

$ iniget file.ini Machine3
app=version1
app=version3

$ iniget file.ini Machine1 app
version1

$ iniget file.ini Machine2 app
version2
version3
Run Code Online (Sandbox Code Playgroud)

再次感谢@John1024 的回答,我正在努力创建一个支持部分的简单 bash ini 解析器。

在 Mac 上使用 GNU bash 测试,版本 5.0.0(1)-release (x86_64-apple-darwin18.2.0)