我在一个更大的脚本中有下面的代码片段,基本上将我的余额从分类帐中取出到两个数组中,这样我就可以按照我想要的方式打印它们。
#!/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
对于循环,您可以使用for
C 风格的循环:
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 变量值。