我正在用bash创建一个程序,使用我创建的数字创建一个histoplot。这些数字是这样存储的(其中第一个数字是文件行上有多少个单词,第二个数字是给定文件中一行中单词数量出现的次数。)
1 1
2 4
3 1
4 2
这应该产生:
1 #
2 ####
3 #
4 ##
但我得到的输出是:
1 #
2 #
3 #
4 #
然而for循环没有意识到我的变量“hashNo”是一个数字。
#!/bin/bash
if [ -e $f ] ; then
while read line
do
lineAmnt=${line% *}
hashNo=${line##* }
#VVVV Problem is this line here VVVV
for i in {1..$hashNo}
#This line ^^^^^^^ the {1..$hashNo}
do
hashes+="#"
done
printf "%4s" $lineAmnt
printf " $hashes\n"
hashes=""
done < $1
fi
如果我用一个数字替换hashNo(例如4在我的输出中产生4个哈希),代码就可以工作但是它需要能够随每一行改变(文件中的所有行都不会有相同数量的字符)
感谢您的帮助:D
答案 0 :(得分:1)
你的循环应该是
for ((i=0; i<hashNo; i++))
do
hashes+="#"
done
此外,您可以使用eval
和命令替换$()
for i in $(eval echo {1..$hashNo})
do
hashes+="#"
done
答案 1 :(得分:1)
我为for循环尝试了这个for (( i=1; i<=$hashNo; i++ ))
,它似乎正在工作
答案 2 :(得分:1)
bash
中的序列表达式必须由整数或字符组成,事先不进行参数替换。这是因为,根据bash
doco:
扩展的顺序是:大括号展开,波浪扩展,参数,变量和算术扩展以及命令替换(以从左到右的方式完成),单词拆分和路径名扩展。
换句话说,大括号扩展(包括序列表达形式)首先发生。
在任何情况下,这都是一种功能,因此可以从任何地方轻松完成,并且效率更高:
#!/bin/bash
hashes() {
sz=$1
while [[ $sz -ge 10 ]]; do
printf "##########"
((sz -= 10))
done
while [[ $sz -gt 0 ]]; do
printf "#"
((sz--))
done
}
echo 1 "$(hashes 1)"
echo 2 "$(hashes 4)"
echo 3 "$(hashes 1)"
echo 4 "$(hashes 2)"
根据需要输出:
1 #
2 ####
3 #
4 ##
第一个循环的使用(一次做十个哈希)几乎肯定会比一次添加一个字符更有效率,如果你愿意,你可以在此之前做一个50的循环,以获得更高的效率如果你的价值可以更大。