简体   繁体   English

newprime.sh:第 14 行:[:0+1:integer 表达式预期

[英]newprime.sh: line 14: [: 0+1: integer expression expected

what's wrong with my code?我的代码有什么问题? I am trying to print prime numbers upto n digits我正在尝试打印最多 n 位的素数

 echo Enter Number
    read num
    for (( i=2; $i <= $num ; i++ ))
    do
            c=0
            for (( j=2; $j <= $i ; j++))
            do
                    mod=$(($i % $j))
                    if  [ "$mod" -eq 0 ]
                    then
                            c=`expr $c+1`
                    fi
            done
            if [ "$c" -eq 1 ]
            then
                    echo $c
    
            fi
    done

I don't have any idea what I'm doing wrong.我不知道我做错了什么。 If someone could tell me how to fix it I would be thankful如果有人能告诉我如何解决它,我将不胜感激

newprime.sh: line 14: [: 0+1: integer expression expected
newprime.sh: line 14: [: 0+1: integer expression expected
newprime.sh: line 14: [: 0+1+1: integer expression expected
newprime.sh: line 14: [: 0+1: integer expression expected
newprime.sh: line 14: [: 0+1+1+1: integer expression expected
newprime.sh: line 14: [: 0+1: integer expression expected

expr requires parameters to be passed as separate arguments. expr要求参数作为单独的 arguments 传递。 Quoting the POSIX standard for expr :引用expr的 POSIX 标准

The application shall ensure that each of the expression operator symbols [...] and the symbols integer and string in the table are provided as separate arguments to expr.应用程序应确保表中的每个表达式运算符符号 [...] 和符号 integer 和字符串作为单独的 arguments 提供给 expr。

The code here is appending all the operators into a single argument, hence your problem.这里的代码将所有运算符附加到一个参数中,因此您的问题。


Thus:因此:

c=$(expr "$c" + 1)

...NOT... ...不是...

c=$(expr $c+1)

But don't do that at all.但千万不要这样做。 It's more efficient and more readable to write:写起来更高效、更易读:

c=$(( c + 1 ))

Optimized with less iterations POSIX shell version:优化了更少的迭代 POSIX shell 版本:

#!/usr/bin/env sh

printf %s 'Enter Number: '
read -r num
i=1
while [ "$i" -le "$num" ]; do
  c=0
  j=2
  # Stop checking division when divisor power 2 is greater than number
  # or we identifed a divisor
  while [ "$((j * j))" -le "$i" ] && [ "$c" -eq 0 ]; do
    c=$((i % j == 0))
    j=$((j + 1))
  done
  if [ "$c" -eq 0 ]; then
    printf '%s\n' "$i"
  fi
  i=$((i + 2))
done

Or using a function:或使用 function:

#!/usr/bin/env sh

is_prime() {
  j=2
  # Check j is a divisor of argument number, while j^2 is less than number
  while [ "$((j * j))" -le "$1" ]; do
    # If j is a divisor of number before the end of the loop
    # number is not prime, so return 1
    [ "$(($1 % j))" -eq 0 ] && return 1
    j=$((j + 1))
  done
}

printf %s 'Enter Number: '
read -r num
i=1
while [ "$i" -le "$num" ]; do
  if is_prime "$i"; then
    printf '%s\n' "$i"
  fi
  i=$((i + 2))
done

Don't use expr .不要使用expr Put your mathematical expression inside (( )) (or echo $(( )) to print the result), and the shell will evaluate it.将您的数学表达式放入(( )) (或echo $(( ))以打印结果),shell 将评估它。

See what the expr output looks like, vs regular shell arithmetic:查看expr output 与常规 shell 算法的对比:

$ expr 0+1
0+1
$ echo "$((0+1))"
1

-eq with test , or single square brackets (eg [ 1 -eq 2 ] ) prints an error if both operands aren't integers. -eq如果两个操作数都不是整数,则带有test或单方括号(例如[ 1 -eq 2 ] )会打印错误。 That's what's causing your error.这就是导致您的错误的原因。

Here's a fast and concise way to list primes in bash.这是列出 bash 中素数的快速简洁的方法。 You can put it in a function or script:您可以将其放入 function 或脚本中:

for ((i=2; i<="${1:?Maximum required}"; i++)); do
    for ((j=2; j<i; j++)); do
        ((i%j)) || continue 2
    done
    echo "$i"
done

edit: Just to explain something, if (([expression])) evaluates to 0 , it returns non-zero ( 1 ) (failure).编辑:只是为了解释一些事情,如果(([expression]))评估为0 ,它返回非零( 1 )(失败)。 If it evaluates to any other number (positive or negative), it returns zero (true).如果计算结果为任何其他数字(正数或负数),则返回零 (true)。 When a number divides evenly in to i , the modulo ( % ) (remainder) is zero.当一个数除以i时,模( % )(余数)为零。 Hence the command fails, we know it's not prime, and we can continue the outer loop, for the next number.因此命令失败,我们知道它不是素数,我们可以continue外循环,以获得下一个数字。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM