Bash 顺序列出数字 1-1000 的脚本,黄色为赔率,绿色为偶数,蓝色为素数
Bash Script that lists numbers 1-1000 sequentially with odds being in yellow, even in green, and primes in blue
显然这是一个 class 作业。我已经玩了几天了。我很容易让奇数和偶数方面工作得很好,但我一直遇到质数方面的问题。
这是odd/even并且有效
#!/bin/bash
for i in $(seq 1000)
do
if (($i % 2));then #even
echo -e "\e[32m$i\e[0m" #green
else #odd
echo -e "\e[33m$i\e[0m" #yellow
fi
done
这是 odd/even/prime 的,我无法让它工作。
#!/bin/bash
for i in $(seq 1000)
do
if (($i % 2));then #even
if
($i -eq factor {2..1000})
echo -e "\e[34m$i\e[0m" #blue
else
echo -e "\e[32m$i\e[0m" #green
fi
else #odd
if
($i -eq factor {2..1000})
echo -e "\e[34m$i\e[0m" #blue
else
echo -e "\e[33m$i\e[0m" #yellow
fi
fi
done
这只是我最近的尝试。我尝试了几种不同的方法,但没有用。一点帮助将不胜感激。也许我做的完全错了,也许我很接近,但我花了很多时间研究这个并且似乎永远无法将它应用到我的脚本中。
遵循质数伪代码 - https://en.wikipedia.org/wiki/Primality_test#Pseudocode ,很容易将其移植到 BASH 脚本:
#! /bin/bash
# Given an integer as an argument
# return 1 if the number is prime, 0 otherwise
function isPrime
{
number=
if [ $number -le 3 ]; then
if [ $number -gt 1 ]; then
return 1
else
return 0
fi
elif [ $(( $number % 2 )) -eq 0 ] || [ $(( $number % 3 )) -eq 0 ]; then
return 0
fi
i=5
while [ $(( $i * $i )) -le $number ]; do
iplus2=$(( $i + 2 ))
if [ $(( $number % $i )) -eq 0 ] || [ $(( $number % $iplus2 )) -eq 0 ]; then
return 0
fi
i=$(( $i + 6 ))
done
return 1
}
没有必要在数值表达式中使用 $
和 $var
符号,例如:$(( x + 1 ))
是可以的,但我故意把它留在那里,因为我认为它代码的操作对于非脚本编写者来说更明显 reader.
BASH 函数不能真正 return 传统编程意义上的值,它基本上是一种退出代码之类的东西。所以 "returned" 值必须通过 $?
.
获得
isPrime
primal=$?
if [ $primal -eq 1 ]; then
echo " is prime"
else
echo " is not prime"
fi
给出输出:
$ ./isPrime.sh 7
7 is prime
$ ./isPrime.sh 8
8 is not prime
很简单。
# from
isPrime() {
if (( == 2 || == 3 )); then
return 0 # prime
fi
if (( % 2 == 0 || % 3 == 0 )); then
return 1 # not a prime
fi
local i w
i=5
w=2
while (( i * i <= )); do
if (( % i == 0 )); then
return 1 # not a prime
fi
i=$((i + w))
w=$((6 - w))
done
return 0 # prime
}
isEven() {
(( % 2 == 0 ))
}
seq 1000 |
while IFS= read -r n; do
if isPrime "$n"; then
echo blue "$n"
elif isEven "$n"; then
echo green "$n"
else
echo yellow "$n"
fi
done
isPrime
函数只是从 this thread 复制而来,它是 google 中搜索 bash how to check for prime number
的第一个结果。修复了它的 return 值,因此如果数字是素数,它 returns 0(成功),如果数字不是素数,它 return 非零,并更改为仅使用算术扩展。
由于 OP 了解如何使用转义序列在终端上打印彩色输出,我只是做了简单的回显以提高可读性。
@edit 修复了 isPrime 函数中的拼写错误 /while/s/==/<=/
@edit,当然 isEven 函数应该被反转......
使用 factor
确定数字是否为质数的基本方法是可行的,但需要做一些工作来提取信息。这个原始代码的修改版本是一种方法:
#!/bin/bash
# A glob pattern to match 'factor' output that has at least two numbers
# separated by whitespace after a colon (e.g. '30: 2 3 5')
composite_factors_glob='*:*[0-9]*[[:space:]]*[0-9]*'
for i in {1..1000} ; do
factors=$(factor "$i")
# shellcheck disable=SC2053
if (( i > 1 )) && [[ $factors != $composite_factors_glob ]] ; then
echo -e "\e[34m$i\e[0m" # prime => blue
elif ((i%2 == 0)) ; then
echo -e "\e[32m$i\e[0m" # even => green
else
echo -e "\e[33m$i\e[0m" # odd => yellow
fi
done
# shellcheck
注释抑制了虚假的 Shellcheck 警告。
显然这是一个 class 作业。我已经玩了几天了。我很容易让奇数和偶数方面工作得很好,但我一直遇到质数方面的问题。
这是odd/even并且有效
#!/bin/bash
for i in $(seq 1000)
do
if (($i % 2));then #even
echo -e "\e[32m$i\e[0m" #green
else #odd
echo -e "\e[33m$i\e[0m" #yellow
fi
done
这是 odd/even/prime 的,我无法让它工作。
#!/bin/bash
for i in $(seq 1000)
do
if (($i % 2));then #even
if
($i -eq factor {2..1000})
echo -e "\e[34m$i\e[0m" #blue
else
echo -e "\e[32m$i\e[0m" #green
fi
else #odd
if
($i -eq factor {2..1000})
echo -e "\e[34m$i\e[0m" #blue
else
echo -e "\e[33m$i\e[0m" #yellow
fi
fi
done
这只是我最近的尝试。我尝试了几种不同的方法,但没有用。一点帮助将不胜感激。也许我做的完全错了,也许我很接近,但我花了很多时间研究这个并且似乎永远无法将它应用到我的脚本中。
遵循质数伪代码 - https://en.wikipedia.org/wiki/Primality_test#Pseudocode ,很容易将其移植到 BASH 脚本:
#! /bin/bash
# Given an integer as an argument
# return 1 if the number is prime, 0 otherwise
function isPrime
{
number=
if [ $number -le 3 ]; then
if [ $number -gt 1 ]; then
return 1
else
return 0
fi
elif [ $(( $number % 2 )) -eq 0 ] || [ $(( $number % 3 )) -eq 0 ]; then
return 0
fi
i=5
while [ $(( $i * $i )) -le $number ]; do
iplus2=$(( $i + 2 ))
if [ $(( $number % $i )) -eq 0 ] || [ $(( $number % $iplus2 )) -eq 0 ]; then
return 0
fi
i=$(( $i + 6 ))
done
return 1
}
没有必要在数值表达式中使用 $
和 $var
符号,例如:$(( x + 1 ))
是可以的,但我故意把它留在那里,因为我认为它代码的操作对于非脚本编写者来说更明显 reader.
BASH 函数不能真正 return 传统编程意义上的值,它基本上是一种退出代码之类的东西。所以 "returned" 值必须通过 $?
.
isPrime
primal=$?
if [ $primal -eq 1 ]; then
echo " is prime"
else
echo " is not prime"
fi
给出输出:
$ ./isPrime.sh 7
7 is prime
$ ./isPrime.sh 8
8 is not prime
很简单。
# from
isPrime() {
if (( == 2 || == 3 )); then
return 0 # prime
fi
if (( % 2 == 0 || % 3 == 0 )); then
return 1 # not a prime
fi
local i w
i=5
w=2
while (( i * i <= )); do
if (( % i == 0 )); then
return 1 # not a prime
fi
i=$((i + w))
w=$((6 - w))
done
return 0 # prime
}
isEven() {
(( % 2 == 0 ))
}
seq 1000 |
while IFS= read -r n; do
if isPrime "$n"; then
echo blue "$n"
elif isEven "$n"; then
echo green "$n"
else
echo yellow "$n"
fi
done
isPrime
函数只是从 this thread 复制而来,它是 google 中搜索 bash how to check for prime number
的第一个结果。修复了它的 return 值,因此如果数字是素数,它 returns 0(成功),如果数字不是素数,它 return 非零,并更改为仅使用算术扩展。
由于 OP 了解如何使用转义序列在终端上打印彩色输出,我只是做了简单的回显以提高可读性。
@edit 修复了 isPrime 函数中的拼写错误 /while/s/==/<=/
@edit,当然 isEven 函数应该被反转......
使用 factor
确定数字是否为质数的基本方法是可行的,但需要做一些工作来提取信息。这个原始代码的修改版本是一种方法:
#!/bin/bash
# A glob pattern to match 'factor' output that has at least two numbers
# separated by whitespace after a colon (e.g. '30: 2 3 5')
composite_factors_glob='*:*[0-9]*[[:space:]]*[0-9]*'
for i in {1..1000} ; do
factors=$(factor "$i")
# shellcheck disable=SC2053
if (( i > 1 )) && [[ $factors != $composite_factors_glob ]] ; then
echo -e "\e[34m$i\e[0m" # prime => blue
elif ((i%2 == 0)) ; then
echo -e "\e[32m$i\e[0m" # even => green
else
echo -e "\e[33m$i\e[0m" # odd => yellow
fi
done
# shellcheck
注释抑制了虚假的 Shellcheck 警告。