【问题标题】:Creating an array of variables in Bash在 Bash 中创建变量数组
【发布时间】:2018-01-17 05:49:04
【问题描述】:

我认为我不能谷歌这个答案的原因是因为我不知道要使用的术语。如果这篇文章令人沮丧,请道歉。

我要创建的是一个多部分变量的数组;这样一组关键字就可以对应一个对应的MQTT主题。背景(与问题无关) - 我打算将自然口语转换为自动化触发器;一旦我有了我的表,一个函数可以将口语句子与我尝试创建的数组/表进行比较,如果关键字匹配,则发送相应的 MQTT 消息。我想使用这种表格/数组的方法,以便于整体解决方案的更新。

在某种想象的语言中,构建此类表的代码可能如下所示:

declare -a commandarray
{"keywords":"'lounge tv on'","mqtt":"lounge/tv{on}"} >> $commandarray
{"keywords":"'lounge tv off'","mqtt":"lounge/tv{off}"} >> $commandarray
{"keywords":"'bedroom tv on'","mqtt":"bedroom/tv{on}"} >> $commandarray
{"keywords":"'bedroom tv off'","mqtt":"bedroom/tv{off}"} >> $commandarray

我猜结果将是一个列标题为“keywords”和“mqtt”的表格,可能会显示为这样。我不在乎它如何显示,这只是为了帮助解释自己。

keywords            mqtt
--------            --------
lounge tv on        lounge/tv{on}       
lounge tv off       lounge/tv{off}       
bedroom tv on       bedroom/tv{on}       
bedroom tv off      bedroom/tv{off} 

任何帮助将不胜感激!

【问题讨论】:

  • 为什么这必须在 bash 中完成?只需选择您选择的脚本语言。
  • bash 是最自然的选择——这适用于家庭自动化,并且 docker 容器被剥离得非常少。我确实找到了那个链接,但它并没有真正涵盖我所追求的(谢谢)。我认为我正在寻找的术语是“哈希表” - 现在谷歌搜索..
  • 我开始认为我应该创建一个单独的 csv 文件。
  • 与哈希表最接近的 bash 是关联数组(仅限 bash v4)。但是关联数组中的条目只是文本,而不是更复杂的数据结构。 bash 并没有真正 数据结构,只是存储文本字符串的各种方式。如果您尝试做任何稍微复杂的事情,那么您真的应该使用 bash 以外的几乎任何语言。你有 Python 吗? Perl?
  • 感谢 Gordon 的确认,我以为我的 google 技能坏了!是的,bash 让事情变得更加困难,但在 docker 容器中,我努力让事情尽可能地纯净。

标签: arrays bash tabular


【解决方案1】:

您需要的是一个称为 关联数组的 bash 4 功能。

declare -A commands=(
  ["lounge tv on"]="lounge/tv{on}"
  ["lounge tv off"]="lounge/tv{off}"
  ["bedroom tv on"]="bedroom/tv{on}"
  ["bedroom tv off"]="bedroom/tv{off}"
)

查找类似于以下内容:

input="lounge tv on"
echo "Running command: ${commands[$input]}"

...分配类似于:

commands["new command"]="new/command{parameter}"

BashFAQ #6the bash-hackers' wiki page on arrays 中详细介绍了关联数组。

【讨论】:

  • 非常感谢您的回答和术语!
【解决方案2】:

最简单的方法是创建一个单独的文件,而不是创建一个表。

这是 commands.txt 的内容:

lounge tv on;lounge/tv{on}
lounge television on;lounge/tv{on}
lounge tv off;lounge/tv{off}
lounge television off;lounge/tv{off}

..以及处理文件的代码:

commandsfile="/config/Scripts/mqtt/commands.txt"
cat $commandsfile | while read command; do
    keywords=$(echo $command | cut -d ";" -f1)
    mqtt=$(echo $command | cut -d ";" -f2)
done

【讨论】:

  • cat $commandsfile 比将< "$commandsfile" 放在循环末尾要麻烦得多。 cat 版本无法处理带有空格的文件名,它会将循环置于子 shell 中,这样它设置的变量在循环退出后不可用 - 此行为在 BashFAQ #24 中进行了描述。
  • 另外,echo $command | cut -d ";" -f1 比一开始就使用 while IFS=';' read -r keywords mqtt _; do 效率更低,漏洞也更多,如BashFAQ #1 中所述。
猜你喜欢
  • 1970-01-01
  • 2014-04-21
  • 1970-01-01
  • 2017-05-26
  • 1970-01-01
  • 2021-04-17
  • 2014-01-17
  • 1970-01-01
  • 2018-06-24
相关资源
最近更新 更多