programing

Bash의 숫자는 어떻게 비교하나요?

jooyons 2023. 4. 10. 21:36
반응형

Bash의 숫자는 어떻게 비교하나요?

수치 비교를 얻을 수 없습니다.

echo "enter two numbers";
read a b;

echo "a=$a";
echo "b=$b";

if [ $a \> $b ];
then
    echo "a is greater than b";
else
    echo "b is greater than a";
fi;

문제는 첫 번째 숫자의 숫자를 비교하는 것입니다.즉, 9는 10보다 크지만 1은 09보다 큽니다.

정확한 비교를 위해 숫자를 유형으로 변환하려면 어떻게 해야 합니까?

Bash에서는 다음 산술 컨텍스트에서 체크를 수행해야 합니다.

if (( a > b )); then
    ...
fi

지원하지 않는 POSIX 쉘의 경우(()), 를 사용할 수 있습니다.-lt그리고.-gt.

if [ "$a" -gt "$b" ]; then
    ...
fi

비교 연산자의 전체 목록은 다음과 같이 얻을 수 있습니다.help test또는man test.

다음과 같이 합니다.

#!/bin/bash

a=2462620
b=2462620

if [ "$a" -eq "$b" ]; then
  echo "They're equal";
fi

정수는 다음 연산자와 비교할 수 있습니다.

-eq # Equal
-ne # Not equal
-lt # Less than
-le # Less than or equal
-gt # Greater than
-ge # Greater than or equal

치트시트 좀 봐

또한 일부 사람들이 알지 못할 수 있는 한 가지 좋은 점이 있습니다.

echo $(( a < b ? a : b ))

이 코드는 다음 중 가장 작은 숫자를 인쇄합니다.a그리고.b

Bash에서는 사용하는 것과 달리 자신을 조건부 조작으로 취급하기 때문에 이 작업을 하는 것이 좋습니다.(( ))산술에 가깝죠

[[ n -gt m ]]

내가 복잡한 일을 하지 않는 한

(( (n + 1) > m ))

하지만 모든 사람들은 그들만의 취향을 가지고 있다.슬픈 것은 어떤 사람들은 그들의 비공식적인 기준을 강요한다는 것이다.

다음 작업도 수행할 수 있습니다.

[[ 'n + 1' -gt m ]]

이 기능을 통해 다른 기능을 추가할 수 있습니다.[[ ]]산술적인 것 말고도 말이야

브래킷 재료(예:[[ $a -gt $b ]]또는(( $a > $b ))float number를 사용해도 충분하지 않습니다.구문 오류가 보고됩니다.플로트 번호 또는 플로트 번호를 정수와 비교하려면(( $(bc <<< "...") )).

예를들면,

a=2.00
b=1

if (( $(bc <<<"$a > $b") )); then 
    echo "a is greater than b"
else
    echo "a is not greater than b"
fi

if 문에 여러 비교를 포함할 수 있습니다.예를들면,

a=2.
b=1
c=1.0000

if (( $(bc <<<"$b == $c && $b < $a") )); then 
    echo "b is equal to c but less than a"
else
    echo "b is either not equal to c and/or not less than a"
fi

숫자 변수(정수)가 숫자 범위 내에 있는지 확인하려는 경우 유용합니다.

한 줄의 솔루션.

a=2
b=1
[[ ${a} -gt ${b} ]] && echo "true" || echo "false"

gt 레퍼런스:https://www.gnu.org/software/bash/manual/html_node/Bash-Conditional-Expressions.html

& & 참조: https://www.gnu.org/software/bash/manual/html_node/Shell-Arithmetic.html

[...] 구성 참조: https://www.gnu.org/software/bash/manual/bash.html#index-_005b_005b

{}달러 레퍼런스: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02 (2.6.2)

파라미터 확장 포맷은 다음과 같습니다.

${세금}

여기서 표현식은 일치하는 '}'까지 모든 문자로 구성됩니다.따옴표로 둘러싸인 문자열 또는 따옴표로 둘러싸인 문자열 내에서 이스케이프된 '}' 및 포함된 산술 확장, 명령 대체 및 변수 확장의 문자는 일치하는 '}'을(를) 결정할 때 검사하지 않습니다.

파라미터 확장을 위한 가장 간단한 형식은 다음과 같습니다.

${파라미터}

이 코드는 플로트를 비교할 수도 있습니다.AWK를 사용하고 있습니다(순수한 Bash가 아닙니다).단, AWK는 표준 POSIX 명령어로 운영체제에 기본적으로 포함되어 있을 가능성이 높기 때문에 이 명령어는 문제가 되지 않습니다.

$ awk 'BEGIN {return_code=(-1.2345 == -1.2345) ? 0 : 1; exit} END {exit return_code}'
$ echo $?
0
$ awk 'BEGIN {return_code=(-1.2345 >= -1.2345) ? 0 : 1; exit} END {exit return_code}'
$ echo $?
0
$ awk 'BEGIN {return_code=(-1.2345 < -1.2345) ? 0 : 1; exit} END {exit return_code}'
$ echo $?
1
$ awk 'BEGIN {return_code=(-1.2345 < 2) ? 0 : 1; exit} END {exit return_code}'
$ echo $?
0
$ awk 'BEGIN {return_code=(-1.2345 > 2) ? 0 : 1; exit} END {exit return_code}'
$ echo $?

사용하기 위해 길이를 줄이려면 다음 기능을 사용합니다.

compare_nums()
{
   # Function to compare two numbers (float or integers) by using AWK.
   # The function will not print anything, but it will return 0 (if the comparison is true) or 1
   # (if the comparison is false) exit codes, so it can be used directly in shell one liners.
   #############
   ### Usage ###
   ### Note that you have to enclose the comparison operator in quotes.
   #############
   # compare_nums 1 ">" 2 # returns false
   # compare_nums 1.23 "<=" 2 # returns true
   # compare_nums -1.238 "<=" -2 # returns false
   #############################################
   num1=$1
   op=$2
   num2=$3
   E_BADARGS=65

   # Make sure that the provided numbers are actually numbers.
   if ! [[ $num1 =~ ^-?[0-9]+([.][0-9]+)?$ ]]; then >&2 echo "$num1 is not a number"; return $E_BADARGS; fi
   if ! [[ $num2 =~ ^-?[0-9]+([.][0-9]+)?$ ]]; then >&2 echo "$num2 is not a number"; return $E_BADARGS; fi

   # If you want to print the exit code as well (instead of only returning it), uncomment
   # the awk line below and comment the uncommented one which is two lines below.
   #awk 'BEGIN {print return_code=('$num1' '$op' '$num2') ? 0 : 1; exit} END {exit return_code}'
   awk 'BEGIN {return_code=('$num1' '$op' '$num2') ? 0 : 1; exit} END {exit return_code}'
   return_code=$?
   return $return_code
}

$ compare_nums -1.2345 ">=" -1.2345 && echo true || echo false
true
$ compare_nums -1.2345 ">=" 23 && echo true || echo false
false

플로트가 있으면 함수를 작성하여 사용할 수 있습니다.예를들면,

#!/bin/bash

function float_gt() {
    perl -e "{if($1>$2){print 1} else {print 0}}"
}

x=3.14
y=5.20
if [ $(float_gt $x $y) == 1 ] ; then
    echo "do stuff with x"
else
    echo "do stuff with y"
fi

작은 함수를 사용하여 버전 문자열을 비교할 수 있는 일반 정수 값으로 변환하여 이 문제를 해결했습니다.

function versionToInt() {
  local IFS=.
  parts=($1)
  let val=1000000*parts[0]+1000*parts[1]+parts[2]
  echo $val
}

여기에는 다음 두 가지 중요한 전제 조건이 있습니다.

  1. 입력은 "일반 SemVer 문자열"입니다.
  2. 각 부품의 범위는 0 ~999입니다

예를들면

versionToInt 12.34.56  # --> 12034056
versionToInt 1.2.3     # -->  1002003

「」의 의 예npm~하다

NPM_ACTUAL=$(versionToInt $(npm --version))  # Capture npm version
NPM_REQUIRED=$(versionToInt 4.3.0)           # Desired version
if [ $NPM_ACTUAL \< $NPM_REQUIRED ]; then
  echo "Please update to npm@latest"
  exit 1
fi

위의 답변에 추가하겠습니다.

single if 문에 여러 표현이 있는 경우 다음과 같은 작업을 수행할 수 있습니다.

if (( $a % 2 == 0 )) && (( $b % 2 != 0));
  then
  echo "What you want to do"
fi

이게 도움이 됐으면 좋겠네요!

언급URL : https://stackoverflow.com/questions/18668556/how-can-i-compare-numbers-in-bash

반응형