如何根据空行将长文本拆分为数组?
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)
其中 #
是不在您的字段中的分隔符。
我有一个包含以下内容的文本文件:
...
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)
其中 #
是不在您的字段中的分隔符。