在 bash 中将变量设置为数组长度时出错

在 bash 中将变量设置为数组长度时出错

我在一个更大的脚本中有下面的代码片段,基本上将我的余额从分类帐中取出到两个数组中,这样我就可以按照我想要的方式打印它们。

#!/bin/bash
assets=("assets:checking" "assets:google wallet" "assets:savings" "assets:cash")
assets-bal=()

num=${#assets[@]}
for $i in {0..${num}}
do
  read -a tmp <<< `ledger -f finances balance "${assets[${i}]}"`
  assets-bal[${i}]=tmp[0]
  echo "${assets[${i}]}   ${assets-bal[${i}]}"
done

每次我尝试运行脚本时都会收到错误:

syntax error near unexpected token `num=${#assets[@]}'
`num=${#assets[@]}'

从我的搜索来看,该行应该没有任何问题,我只是一直空着试图找到它不起作用的原因。

有人能指出我错在哪里吗?

答案1

问题可能是

assets-bal=()

变量名称不得包含破折号。您只能使用下划线。

我不知道如何bash解释assets-bal=(),但它认为命令不完整,必须在另一行完成。只需在 shell 中运行该行即可明白我的意思。

答案2

大括号扩展不支持变量,因为它已完成在变量扩展之前seq如果您绝对必须,请改用:

for i in $(seq 0 ${num})

或者(更好)直接获取数组键:

for i in "${!assets[@]}"

(另外,,for i in ..不是for $i in ..。)


豪克拉格遇到第一个错误。一旦你解决了这个问题,这可能就是下一个错误。


而不是

read -a tmp <<< `ledger -f finances balance "${assets[${i}]}"`

考虑使用:

tmp=($(ledger -f finances balance "${assets[${i}]}"))

外部()命令替换将其转换为数组。

答案3

您有一个语法错误:您不能-在变量名称中使用。

assets-bal

应替换为

 assets_bal   

对于循环,您可以使用forC 风格的循环:

for ((i=0; i<${num}; i++)); do

答案4

我认为你可能过于依赖数组类型 - 以及一般变量。如果我正确理解了你在上面做的事情,我怀疑这应该会做同样的事情:

for a in checking google\ wallet savings cash
do  a=assets:$a
    printf "$a\t%d\n" "$(ledger -f finances balance "$a")"
done

$a通过某种方式在流中一次读取上述所有值,然后使用类似sed或类似的脚本编辑器进行排列,这可能会得到很大的改进。一般来说,shell 变量是一个非常糟糕的地方来保存任何值的信息 - 或者任何重要大小的信息。 shell 变量应该只存储足够的信息,以便从文件中检索实际信息更易于管理。

编写为 shell 函数,上面的代码可能如下所示:

assets() if   [ "$#" -gt 0 ]
         then while [ "$#" -gt 0 ]
              do    printf "assets:%s\t%d\n" "$1" "$(
                    ledger -f finances balance "assets:$1")"
              shift;done
         else assets checking google\ wallet savings cash
         fi

...并且可以这样称呼:

assets

...您的默认列表,或者类似...

assets cash checking

...对于不同的列表,根本不需要设置单个 shell 变量值。

相关内容