두 숫자의 최소/최대값을 제공할 수 있는 유닉스 명령이 있습니까?

두 숫자의 최소/최대값을 제공할 수 있는 유닉스 명령이 있습니까?

에서 읽는 양을 제한하는 명령을 찾고 있습니다 stdin.

나는 이 목적을 위해 작은 스크립트를 작성했지만(비판 환영) 이렇게 간단하고 일반적인 사용 사례를 달성하기 위한 표준 명령이 없는지 궁금합니다.

내 스크립트를 찾았습니다.최저 한도에서두 개의 숫자:

#!/bin/bash
# $1 limit

[ -z "$1" ] && { echo "Needs a limit as first argument." >&2; exit 1; }

read number

if [ "$number" -gt "$1" ]; then
        echo "$1"
else
        echo "$number"
fi

답변1

a두 정수 의 합을 다루고 있다는 것을 알고 있다면 b다음과 같이 간단합니다.삼항 연산자를 사용한 쉘 산술 확장숫자 최대값을 제공하는 것으로 충분합니다.

$(( a > b ? a : b ))

수치적 최소값은 다음과 같습니다.

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

예를 들어

$ a=10
$ b=20
$ max=$(( a > b ? a : b ))
$ min=$(( a < b ? a : b ))
$ echo $max
20
$ echo $min
10
$ a=30
$ max=$(( a > b ? a : b ))
$ min=$(( a < b ? a : b ))
$ echo $max
30
$ echo $min
20
$ 

이를 보여주는 쉘 스크립트는 다음과 같습니다.

#!/usr/bin/env bash
[ -z "$1" ] && { echo "Needs a limit as first argument." >&2; exit 1; }
read number
echo Min: $(( $number  < $1 ? $number : $1 ))
echo Max: $(( $number  > $1 ? $number : $1 ))

답변2

sort그리고 head이것을 할 수 있습니다:

numbers=(1 4 3 5 7 1 10 21 8)
printf "%d\n" "${numbers[@]}" | sort -rn | head -1       # => 21

답변3

두 숫자만 비교할 수 있습니다 dc.

dc -e "[$1]sM $2d $1<Mp"

... "$1"최대값은 어디에 있고, 이 "$2"값이 .보다 작을 경우 인쇄할 숫자는 입니다 "$1". 여기에는 GNU도 필요합니다 dc. 하지만 이식성 있게 동일한 작업을 수행할 수 있습니다. 예를 들면 다음과 같습니다.

dc <<MAX
    [$1]sM $2d $1<Mp
MAX

위의 두 경우 모두 정밀도를 0이 아닌 값으로 설정할 수 있습니다.(기본)좋다 ${desired_precision}k. 두 가지 모두에 대해 두 값이 모두 맞는지 확인해야 합니다.확실히 숫자야교환원을 통해 전화를 걸 dc수 있기 때문이죠 .system()!

다음 작은 스크립트를 사용하십시오(그리고 다음 것)또한 입력의 유효성을 검사해야 합니다(예: grep -v \!|dc임의의 입력을 강력하게 처리하는 것). 또한 접두어 대신 접두어로 음수를 해석하는 방법도 알아야 합니다 dc. 왜냐하면 후자가 빼기 연산자이기 때문입니다._-

무엇보다도 이 스크립트는 각 값이나 입력에 대해 제공하고 인쇄하려는 연속된 줄로 구분된 숫자 중 더 작은 숫자를 dc읽습니다 .\n$max

dc -e "${max}sm
       [ z 0=? d lm<M p s0 lTx ]ST
       [ ? z 0!=T q ]S?
       [ s0 lm ]SM lTx"

그래서... [대괄호 안의 모든 확장 ]dc 각 객체는 해당 배열( 또는 )에 저장됩니다 S. 다른 일 외에도 할 수 있는 일T?Mdcx, 매크로로 실행할 수도 있습니다 . 적절하게 정리하면 작고 완전한 기능을 갖춘 dc스크립트를 간단하게 조립할 수 있습니다.

dc그 일을 수행하다더미. 모든 입력 객체는 마지막 객체 위에 쌓입니다. 각각의 새로운 입력 객체가 추가되면 마지막 맨 위 객체와 그 아래의 모든 객체가 스택에서 하나씩 아래로 푸시됩니다. 객체에 대한 대부분의 참조는 최상위 스택 값에 대한 참조이며 대부분의 참조는대중 음악스택의 상단(아래의 모든 개체를 하나씩 위로 당깁니다.).

메인 스택 외에도(적어도)256개의 배열, 각 배열 요소에는 자체 스택이 있습니다. 여기서는 많이 사용하지 않습니다. l필요할 때 로드하고 x조건부로 실행할 수 있도록 언급한 대로 문자열을 저장 하고 s값을 $max배열 상단에 저장합니다 m.

어쨌든 이것은 dc주로 쉘 스크립트가 수행하는 작업입니다. 일반적으로 표준 입력에서 인수를 가져오는 GNU-ism -e옵션을 사용 하지만 다음과 같이 할 수 있습니다.dc

echo "$script" | cat - /dev/tty | dc

... $script위의 비트와 같다면.

작동 방식은 다음과 같습니다.

  • lTx- 상단에 저장된 매크로가 l실행됩니다 .xT (테스트 목적으로 추측합니다. 일반적으로 임의로 이러한 이름을 선택합니다.).
  • z 0=?- est 는 스택이 비어 있으면 T스택 깊이를 테스트합니다.z(읽기: 0개의 객체를 보유함)?매크로를 호출합니다 .
  • ? z0!=T q- 이 ?매크로는 ? dcstdin에서 입력 줄을 읽는 내장 명령의 이름을 따서 명명 되었지만 빈 줄을 가져오거나 EOF에 도달하면 전체 애플릿을 실행할 수 z있도록 또 다른 스택 깊이 테스트도 추가했습니다 . q그러나 !스택을 성공적으로 채우지 못하면 Test가 다시 호출됩니다.
  • d lm<M- Test는 d스택의 맨 위를 복사하여 다음과 비교합니다.$max (에 저장된 경우 m). m값이 더 작으면 매크로 가 dc호출됩니다 M.
  • s0 lm- M스택의 상단을 팝하고 가상 스칼라에 덤프하면 됩니다 0. 스택을 팝하는 저렴한 방법입니다. 동쪽으로 돌아가기 전에 다시 로드됩니다 l.mT
  • p- 이는 m현재 스택 상단보다 작 으면 m교체한다는 의미입니다.( d어쨌든 중복이군요)여기에 인쇄됩니다 p. 그렇지 않으면 인쇄되지 않으며 입력 내용이 무엇이든 p인쇄됩니다.
  • s0- 후에( p스택이 팝되지 않기 때문에)우리는 스택의 상단을 다시 덤프 0하고...
  • lTx- l재귀적으로 다시 로드 T하고 x다시 실행합니다.

따라서 이 작은 코드 조각을 실행하고 터미널에서 대화형으로 숫자를 입력하면 dc입력한 숫자가 다시 인쇄 되거나 $max입력한 숫자가 더 큰 경우 값이 인쇄됩니다. 또한 모든 파일을 허용합니다.(예: 파이프)표준 입력으로. 빈 줄이나 EOF를 만날 때까지 읽기/비교/인쇄 루프를 계속합니다.

이에 대한 몇 가지 참고 사항 - 저는 쉘 함수의 동작을 시뮬레이션하기 위해 이것을 작성했습니다. 따라서 한 줄에 하나의 숫자만 안정적으로 처리할 수 있습니다. dc그러나 한 줄에 공백으로 구분된 숫자를 원하는 만큼 처리할 수 있습니다.하지만, 스택으로 인해 한 줄의 마지막 숫자는 작동하는 첫 번째 숫자가 됩니다. 따라서 작성된 대로 한 dc줄에 여러 숫자를 인쇄/입력하면 출력이 반대로 인쇄됩니다. 이를 수행하는 올바른 방법은 행을 배열에 저장한 다음 처리하는 것입니다.

이와 같이:

dc -e "${max}sm
    [ d lm<M la 1+ d sa :a z0!=A ]SA
    [ la d ;ap s0 1- d sa 0!=P ]SP 
    [ ? z 0=q lAx lPx l?x ]S?
    [q]Sq [ s0 lm ]SM 0sa l?x"

그런데...이것을 더 깊이 설명하고 싶은지 모르겠습니다. dc스택의 각 값을 읽을 때 $max해당 값 또는 인덱스 배열에 값을 저장하고, 스택이 다시 비어 있음을 감지하면 다른 인덱스 개체 입력 행을 읽으려고 시도하기 전에 각 값을 인쇄합니다. .

그래서 첫 번째 스크립트가 수행하는 동안 ...

10 15 20 25 30    ##my input line
20
20
20
15
10                ##see what I mean?

두 번째는 다음과 같습니다.

10 15 20 25 30    ##my input line
10                ##that's better
15
20
20                ##$max is 20 for both examples
20

먼저 이 명령을 사용하여 설정하면 임의의 정밀도 부동 소수점 숫자를 처리할 수 있습니다 k. i입력 또는 출력 기반을 독립적으로 변경할 수 있습니다 o. 이는 예상치 못한 이유로 유용할 때도 있습니다. 예를 들어:

echo 100000o 10p|dc
 00010

...먼저 dc출력 기준을 100000으로 설정한 다음 10을 인쇄합니다.

답변4

미리 정의된 수학 함수 라이브러리를 정의한 bc다음 명령줄에서 사용할 수 있습니다.

예를 들어 다음과 같은 콘텐츠를 텍스트 파일에 포함합니다 ~/MyExtensions.bc.

define max(a,b){
  if(a>b)
  { 
   return(a)
  }else{
   return(b)
  }
}

이제 다음 bc을 통해 전화할 수 있습니다.

> echo 'max(60,54)' | bc ~/MyExtensions.bc
60

참고로 무료 수학 라이브러리 함수가 있습니다.이와 같은사용 가능한 온라인.

이 파일을 사용하면 다음과 같은 더 복잡한 함수를 쉽게 계산할 수 있습니다 GCD.

> echo 'gcd (60,54)' | bc ~/extensions.bc -l
6

관련 정보