2つの数字の最小/最大値を提供できるUnixコマンドはありますか?

2つの数字の最小/最大値を提供できるUnixコマンドはありますか?

で読む量を制限するコマンドを探していますstdin

私はこの目的のために小さなスクリプトを書いていますが(批判を歓迎します)、これは単純で一般的なユースケースを達成するための標準コマンドがないかどうか疑問に思います。

私のスクリプトを見つけました。最低限度で2つの数字:

#!/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

a2つの整数の合計を扱っていることがわかっている場合は、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

2つの数字のみを比較できますdc

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

..."$1"最大値はどこにあり、この"$2"値が.より小さい場合に印刷する数字はです"$1"。これにはGNUも必要ですdc。ただし、移植可能に同じ操作を実行できます。たとえば、次のようになります。

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

上記のいずれの場合も、精度をゼロ以外の値に設定できます。(基本)良い${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?Mdcひもx、マクロとして実行することもできます。適切にクリーンアップすると、コンパクトでフル機能のdcスクリプトを簡単に組み立てることができます。

dcその仕事をする。すべての入力オブジェクトは最後のオブジェクトの上に積み重ねられます。それぞれの新しい入力オブジェクトが追加されると、最後の一番上のオブジェクトとその下のすべてのオブジェクトがスタックから1つずつ下にプッシュされます。オブジェクトへのほとんどの参照は最上位のスタック値への参照であり、ほとんどの参照はポップミュージックスタックの上部(下のすべてのオブジェクトを1つずつ引き上げます。)

メインスタックに加えて(少なくとも)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 (に保存されている場合mm値が小さい場合、マクロがdc呼び出されますM
  • s0 lm-Mスタックの上部をポップして仮想スカラーにダンプします0。スタックをポップする安価な方法です。東に戻る前にリロードされますlmT
  • p- これは、m現在のスタックの上部より小さい場合はm交換することを意味します。dとにかく重複ですね)ここに印刷されますp。それ以外の場合は印刷されず、入力内容は何でも印刷さpれます。
  • s0- 後pスタックがポップされないため)私たちはスタックの上部をもう一度ダンプしています0...
  • lTx-l再帰的に再ロードしTx再実行します。

したがって、この小さなコードスニペットを実行して端末でインタラクティブに数字を入力すると、dc入力した数字が再印刷されるか、$max入力した数字が大きい場合に値が印刷されます。また、すべてのファイルを受け入れます。(例:パイプ)標準入力として。空白行またはEOFに会うまで、読み取り/比較/印刷ループを続けます。

これに関するいくつかの注意 - 私はシェル関数の動作をシミュレートするためにこれを書いています。したがって、1行に1つの数字のみを確実に処理できます。dcただし、1行にスペースで区切られた数字を好きなだけ処理できます。しかし、、スタックのため、1行の最後の数字は動作する最初の数字になります。したがって、作成されたとおりに1dc行に複数の数字を印刷/入力すると、出力は逆に印刷されます。これを行う正しい方法は、行を配列に保存して処理することです。

このように:

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?

2番目は次のとおりです。

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

まず、このコマンドを使用して設定すると、任意の精度浮動小数点数を処理できますki入力または出力ベースを独立して変更できます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

関連情報