【问题标题】:bash - Error with getopts argument in histogram plot scriptbash - 直方图脚本中的 getopts 参数出错
【发布时间】:2017-04-18 10:29:40
【问题描述】:

到目前为止,这是我的代码(我是 bash 新手,所以我知道它可能很乱):

#!/bin/bash

while getopts ":cs:p:" opt; do
    case $opt in
        c)COUNT="hello";;
        s)NUM=$OPTARG;;
        p)CHAR="$OPTARG";;
        \?) exit 1;;
    esac
done

shift $((OPTIND - 1))

while read number value; do
    printf "%3d " $number
    if [ ! -z $COUNT ]; then
        printf "%5d " $value
    fi
    if [ $NUM ]; then
        for i in $(seq 1 {$value/$NUM}); do
            if [ ! -z $CHAR ]; then
                printf "%s" $CHAR
            else
                printf "#"
            fi
        done
    else
        for i in $(seq 1 $value); do
            if [ ! -z $CHAR ]; then
                printf "%s" $CHAR
            else
                printf "#"
            fi
        done
    fi
    printf "\n"
done <${1:-/dev/stdin}

因此,此代码所做的是以 {line length,occurrances} 或 {x, y} 格式的输入行,脚本将绘制具有行长的数据以及“#”的直方图字符。

第一个问题:

我的 getopts 工作正常,除了“-s NUM”,它在尝试将 $value 除以 $NUM(要除以的输入数字)时输出错误。这应该减少使用 NUM 作为标量打印的 # 个字符的数量。 我可以完全正常地运行命令“./histoplot -c -p '$' textfile.txt”,它完成了它需要做的事情。但是当我运行“./histoplot -s 3 textfile.txt”时,它会输出错误:seq: invalid floating point argument: '{x/y}

我该怎么做才能使这项工作正常进行?

第二个问题:

所以输入文件包含:

3 4
4 1
5 3
10 1

输出应该是(对于命令“./histoplot -c [or any other option] [inputfile]”:

  1    0
  2    0
  3    4 ####
  4    1 #
  5    3 ###
  6    0
  7    0
  8    0
  9    0
 10    1 #

但是我的输出不包含出现 0 次的长度。 有什么想法吗?

提前感谢大家的帮助,我真的很感激!

编辑:

第一个问题已经解决,只剩下第二个问题了。有人有什么想法吗? :)

【问题讨论】:

  • 另外,由 $value/$NUM 确定的数字需要向下舍入,因此如果等于 4.57,则打印的字符数将为 4。

标签: bash shell unix


【解决方案1】:

你的第一个问题的原因是因为

for i in $(seq 1 {$value/$NUM});

在语法上不正确,因为您没有在算术上下文中使用变量,所以在 bash 中使用运算符 $((..)) 和 C 风格的 for-loop 就可以了

for ((i=1; i<=$((value/NUM)); i++));

另外,bash 不进行浮点运算,并且在用于整数除法时总是将向下四舍五入到最低位。

【讨论】:

  • 感谢您的帮助,它工作正常!这是否总是自动四舍五入?比如,x/y = 4.57 = 4?
  • @Swallows:是的,请参考我的更新,您可以自己手动确认,在执行echo $((7/4)) 时,它会为1.75 生成1
  • 您是传奇人物,感谢您的帮助!对问题 2 有任何想法吗? :)
  • @Swallows:我不确定我是否收到你的2nd logic,也许你需要重新审视你的设计。代码不可能以现有形式打印您需要的输出
最近更新 更多