에서 읽는 양을 제한하는 명령을 찾고 있습니다 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
?
M
dc
끈x
, 매크로로 실행할 수도 있습니다 . 적절하게 정리하면 작고 완전한 기능을 갖춘 dc
스크립트를 간단하게 조립할 수 있습니다.
dc
그 일을 수행하다더미. 모든 입력 객체는 마지막 객체 위에 쌓입니다. 각각의 새로운 입력 객체가 추가되면 마지막 맨 위 객체와 그 아래의 모든 객체가 스택에서 하나씩 아래로 푸시됩니다. 객체에 대한 대부분의 참조는 최상위 스택 값에 대한 참조이며 대부분의 참조는대중 음악스택의 상단(아래의 모든 개체를 하나씩 위로 당깁니다.).
메인 스택 외에도(적어도)256개의 배열, 각 배열 요소에는 자체 스택이 있습니다. 여기서는 많이 사용하지 않습니다. l
필요할 때 로드하고 x
조건부로 실행할 수 있도록 언급한 대로 문자열을 저장 하고 s
값을 $max
배열 상단에 저장합니다 m
.
어쨌든 이것은 dc
주로 쉘 스크립트가 수행하는 작업입니다. 일반적으로 표준 입력에서 인수를 가져오는 GNU-ism -e
옵션을 사용 하지만 다음과 같이 할 수 있습니다.dc
echo "$script" | cat - /dev/tty | dc
... $script
위의 비트와 같다면.
작동 방식은 다음과 같습니다.
lTx
- 상단에 저장된 매크로가l
실행됩니다 .x
T
(테스트 목적으로 추측합니다. 일반적으로 임의로 이러한 이름을 선택합니다.).z 0=?
- est 는 스택이 비어 있으면T
스택 깊이를 테스트합니다.z
(읽기: 0개의 객체를 보유함)?
매크로를 호출합니다 .? z0!=T q
- 이?
매크로는?
dc
stdin에서 입력 줄을 읽는 내장 명령의 이름을 따서 명명 되었지만 빈 줄을 가져오거나 EOF에 도달하면 전체 애플릿을 실행할 수z
있도록 또 다른 스택 깊이 테스트도 추가했습니다 .q
그러나!
스택을 성공적으로 채우지 못하면T
est가 다시 호출됩니다.d lm<M
-T
est는d
스택의 맨 위를 복사하여 다음과 비교합니다.$max
(에 저장된 경우m
).m
값이 더 작으면 매크로 가dc
호출됩니다M
.s0 lm
-M
스택의 상단을 팝하고 가상 스칼라에 덤프하면 됩니다0
. 스택을 팝하는 저렴한 방법입니다. 동쪽으로 돌아가기 전에 다시 로드됩니다l
.m
T
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