从命令输出生成关联数组
Generate an associative array from command output
我正在编写一个 zsh 完成函数来完成数据库中的 ID。有一个程序 listnotes
输出这样的列表:
bf848bf6-63d2-474b-a2c0-e7e3c4865ce8 Note Title
aba21e55-22c6-4c50-8bf6-bf3b337468e2 Another one
09ead915-bf2d-449d-a943-ff589e79794a yet another "one"
...
如何根据 listnotes
命令的输出生成关联数组 note_ids
,以便获得这样的关联数组?
( bf848bf6-63d2-474b-a2c0-e7e3c4865ce8 "Note Title" aba21e55-22c6-4c50-8bf6-bf3b337468e2 "Another one" 09ead915-bf2d-449d-a943-ff589e79794a "yet another \"one\"" )
请注意,键中可能有空格。我试图用 sed
:
生成一些东西
note_ids=($(listnotes | sed 's/^\(.*\) \(.*\)$/ ""/'))
但像这样引用字符串似乎行不通,标题中的双引号使它变得更加困难。
试试
typeset -A note_ids
for line in ${(f)"$(listnotes)"}; do
note_ids+=(${line%% *} ${line#* })
done
${(f)PARAM}
:将$PARAM
展开的结果拆分为换行符
"$(listnotes)"
:将listnotes
的输出逐字放入展开式。
for line in LIST
:遍历 LIST
中被 ${(f)…}
分割的项目。
note_ids+=(key value)
:将 key-value 对添加到关联数组 note_ids
${line%% *}
:从line
的扩展末尾切掉匹配" *"
的最大部分(一个space后跟任何东西)。因此,在包含第一个 space 之后删除所有内容,只留下密钥。
${line#* }
:从$line
的展开开始切掉匹配"* "
的最小部分(后面跟三个space的任何东西)。因此,删除密钥和用作分隔符的三个 space。
除了使用参数扩展标志 (f)
,您还可以使用 read
:
逐行读取 listnotes
的输出
listnotes | while read; do
note_ids+=(${REPLY%% *} ${REPLY#* })
done
除非另有说明,否则 read
将读取的值放入 REPLY
参数。
我正在编写一个 zsh 完成函数来完成数据库中的 ID。有一个程序 listnotes
输出这样的列表:
bf848bf6-63d2-474b-a2c0-e7e3c4865ce8 Note Title
aba21e55-22c6-4c50-8bf6-bf3b337468e2 Another one
09ead915-bf2d-449d-a943-ff589e79794a yet another "one"
...
如何根据 listnotes
命令的输出生成关联数组 note_ids
,以便获得这样的关联数组?
( bf848bf6-63d2-474b-a2c0-e7e3c4865ce8 "Note Title" aba21e55-22c6-4c50-8bf6-bf3b337468e2 "Another one" 09ead915-bf2d-449d-a943-ff589e79794a "yet another \"one\"" )
请注意,键中可能有空格。我试图用 sed
:
note_ids=($(listnotes | sed 's/^\(.*\) \(.*\)$/ ""/'))
但像这样引用字符串似乎行不通,标题中的双引号使它变得更加困难。
试试
typeset -A note_ids
for line in ${(f)"$(listnotes)"}; do
note_ids+=(${line%% *} ${line#* })
done
${(f)PARAM}
:将$PARAM
展开的结果拆分为换行符"$(listnotes)"
:将listnotes
的输出逐字放入展开式。for line in LIST
:遍历LIST
中被${(f)…}
分割的项目。note_ids+=(key value)
:将 key-value 对添加到关联数组note_ids
${line%% *}
:从line
的扩展末尾切掉匹配" *"
的最大部分(一个space后跟任何东西)。因此,在包含第一个 space 之后删除所有内容,只留下密钥。${line#* }
:从$line
的展开开始切掉匹配"* "
的最小部分(后面跟三个space的任何东西)。因此,删除密钥和用作分隔符的三个 space。
除了使用参数扩展标志 (f)
,您还可以使用 read
:
listnotes
的输出
listnotes | while read; do
note_ids+=(${REPLY%% *} ${REPLY#* })
done
除非另有说明,否则 read
将读取的值放入 REPLY
参数。