如何根据空行将长文本拆分为数组?

How can I split a long text into array based on empty lines?

我有一个包含以下内容的文本文件:

...
LogLevelMax=-1
Id=keyboard-setup.service

LogLevelMax=-1
Id= networkd-dispatcher.service

LogLevelMax=-1
Id=systemd-remote-fs.service

LogLevelMax=-1
Id=systemd-journal-flush.service

LogLevelMax=-1
Id=some-other.service
...

我想将它们保存到一个关联数组中,作为键 'Id',值 'LogLevelMax'。 每个“实体”之间恰好有 2 条新行。在 LogLevelMax 和 Id 之间正好有一个新行。

首先,我尝试用字符“#”替换 2 个空行: cat file.txt | tr "\n\n" "#"。但它用“#”替换了所有新行,而不仅仅是 2 个新行。

如何在 bash 中使用 sed、awk、regex 或 bash 函数来实现? 谢谢

与bash:

declare -A array
while IFS='=' read -r a b; do
  if [[ "$a" == "Id" ]]; then
    array+=(["$b"]="$c")
  fi
  c="$b"
done < file

然后:

$ for k in "${!array[@]}"; do printf '%s : %s\n' "$k" "${array[$k]}"; done
systemd-journal-flush.service : -1
keyboard-setup.service : -1
systemd-remote-fs.service : -1
networkd-dispatcher.service : -1
some-other.service : -1

awk:

parse.awk

BEGIN {
  RS=""
  FS=" *[\n=] *"
}

# Copy references into the h associative array
{ h[] =  }

# Print collected key/value pairs
END { 
  for (k in h) 
    print k " -> " h[k]
}

运行 例如像这样:

awk -f parse.awk infile | column -t

输出:

networkd-dispatcher.service    ->  -1
keyboard-setup.service         ->  -1
systemd-remote-fs.service      ->  -1
systemd-journal-flush.service  ->  -1
some-other.service             ->  -1

我会这样使用 awk 和 Bash:

declare -A aarr

while read -r key val; do
    aarr["$key"]="$val"
done < <(awk '{print , }' RS='\n\n' FS="[[:space:]]*[=\n][[:space:]]*" file)

结果:

$ declare -p aarr
declare -A aarr=([systemd-journal-flush.service]="-1" [keyboard-setup.service]="-1" [systemd-remote-fs.service]="-1" [networkd-dispatcher.service]="-1" [some-other.service]="-1" )

如果字段中可能有空格,您可以这样做:

while IFS=# read -r key val; do
    aarr["$key"]="$val"
done < <(awk '{print  "#" }' RS= FS="[[:space:]]*[=\n][[:space:]]*" file)

其中 # 是不在您的字段中的分隔符。