如何精简输出结果为英文单词的Bash计算器脚本?
Refactoring Your Bash Calculator to Avoid Endless
if/elif Blocks Absolutely! Those messy if/elif chains are exactly the kind of thing we can clean up with arrays—way more maintainable, especially when you need to extend support up to 30. Let’s break down how to refactor your script properly:
First, let’s fix a couple of small syntax bugs in your original code:
- The shebang line should be
#!/bin/bash(you missed the slash beforebin) - Conditions like
[ $ans == 7]are missing a space before the closing bracket, which would throw errors
Now, the core fix: replace all those if/elif checks with a numeric array that maps each number (0-30) directly to its English word equivalent. This makes extending to 30 trivial, and the code way cleaner.
Here’s the refactored script:
#!/bin/bash # Array mapping numbers 0-30 to their English word counterparts declare -a num_words=( [0]="zero" [1]="one" [2]="two" [3]="three" [4]="four" [5]="five" [6]="six" [7]="seven" [8]="eight" [9]="nine" [10]="ten" [11]="eleven" [12]="twelve" [13]="thirteen" [14]="fourteen" [15]="fifteen" [16]="sixteen" [17]="seventeen" [18]="eighteen" [19]="nineteen" [20]="twenty" [21]="twenty-one" [22]="twenty-two" [23]="twenty-three" [24]="twenty-four" [25]="twenty-five" [26]="twenty-six" [27]="twenty-seven" [28]="twenty-eight" [29]="twenty-nine" [30]="thirty" ) while true; do # Get input numbers with basic validation (optional but helpful) read -p "First number: " n1 if ! [[ $n1 =~ ^[0-9]+$ ]]; then echo "Please enter a valid whole number." continue fi read -p "Second number: " n2 if ! [[ $n2 =~ ^[0-9]+$ ]]; then echo "Please enter a valid whole number." continue fi # Select operation PS3="What's the operation? " select ans in add subtract multiply divide; do case $ans in add) op='+' ; break ;; subtract) op='-' ; break ;; multiply) op='*' ; break ;; divide) op='/' ; break ;; *) echo "Invalid response, please try again." ;; esac done # Calculate result and convert to integer (handles bc's floating-point output) result=$(echo "$n1 $op $n2" | bc -l) int_result=$(printf "%.0f" "$result") # Round to nearest whole number # Check if result is within our supported range and output if [[ $int_result -ge 0 && $int_result -le 30 ]]; then printf "%s %s %s = %s\n" "$n1" "$op" "$n2" "${num_words[$int_result]}" else echo "Oops! Result ($int_result) is outside the 0-30 range we support." fi done
Key Improvements:
- No more
if/elifhell: The array lets us look up the word in one line with${num_words[$int_result]} - Handles floating-point results:
bc -loutputs decimals (e.g.,1.000000), so we round to an integer to match our array indices - Input validation: Added checks to ensure users enter valid whole numbers (prevents errors from non-numeric input)
- Range checking: Tells users if their result is outside the 0-30 range instead of silently failing
- Easy to extend: To support numbers beyond 30, just add more entries to the
num_wordsarray
内容的提问来源于stack exchange,提问作者melkor787
相关产品推荐
相关产品推荐

