क्या एक यूनिक्स कमांड है जो न्यूनतम / अधिकतम दो नंबर देता है?


37

में से पढ़ी गई संख्या को सीमित करने के लिए मैं एक कमांड की तलाश में था 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

जवाबों:


20

आप इस 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मूल्य या इनपुट के लिए प्रिंट करें , जिसके आधार पर wo की कम है:

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

तो ... तो उनमें से प्रत्येक [वर्ग कोष्ठकों के भीतर ]विस्तार एक है dc स्ट्रिंग उद्देश्य यह है कि है Sमें से किसी एक - अपने संबंधित सरणी के लिए प्रत्येक aved T, ?, या M। कुछ अन्य चीजों के अलावा dcएक स्ट्रिंग के साथ कर सकते हैं, यह भी xएक एक के रूप में ई एक्यूट कर सकते हैं । यदि आप इसे सही ढंग से व्यवस्थित करते हैं तो पूरी तरह से काम करने वाली dcलिपि को पर्याप्त रूप से इकट्ठा किया जाता है।

dcएक स्टैक पर काम करता है । सभी इनपुट ऑब्जेक्ट को अंतिम पर स्टैक्ड किया जाता है - प्रत्येक नई इनपुट ऑब्जेक्ट अंतिम टॉप ऑब्जेक्ट को धक्का देती है और इसके नीचे सभी ऑब्जेक्ट्स को एक से एक करके जोड़ दिया जाता है। किसी ऑब्जेक्ट के अधिकांश संदर्भ शीर्ष स्टैक मान के लिए होते हैं, और अधिकांश संदर्भ पॉप के ऊपर होते हैं जो स्टैक के शीर्ष (जो एक के ऊपर एक करके सभी वस्तुओं को नीचे खींचता है)

मुख्य स्टैक के अलावा, इसमें (कम से कम) 256 ऐरे भी होते हैं और प्रत्येक एरे तत्व अपने सभी स्टैक के साथ आता है। मैं यहाँ बहुत का उपयोग नहीं करते। मैं सिर्फ स्ट्रिंग के रूप में उल्लेख किया है तो मैं कर सकते हैं की दुकान lउन्हें जब चाहता था oad और ई xउन्हें ecute सशर्त, और मैं sफाड़ $maxके शीर्ष में के मूल्य mसरणी।

वैसे भी, यह थोड़ा सा dc, बड़े पैमाने पर, आपकी शेल-स्क्रिप्ट क्या करता है। यह GNU-ism -eविकल्प का उपयोग करता है - जैसा कि dcआम तौर पर अपने मापदंडों को मानक-इन से लेता है - लेकिन आप ऐसा ही कर सकते हैं:

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

... अगर $scriptउपरोक्त बिट की तरह देखा।

यह इस तरह काम करता है:

  • lTx- यह lओड्स और ई परीक्षणx के शीर्ष में संग्रहीत मैक्रो का T परीक्षण करता है (मुझे लगता है - मैं आमतौर पर उन नामों को मनमाने ढंग से चुनता हूं)
  • z 0=?- Tस्था तो स्टैक डेप्थ w / zऔर का परीक्षण करता है , यदि स्टैक खाली है (पढ़ें: 0 ऑब्जेक्ट्स रखता है) यह ?मैक्रो कहता है ।
  • ? z0!=T q- ?मैक्रो को ? dcबिलिन कमांड के लिए नामित किया गया है जो स्टड से इनपुट की एक पंक्ति को पढ़ता है, लेकिन मैंने इसके साथ एक और zस्टैक डेप्थ टेस्ट भी जोड़ा है, ताकि qअगर यह एक खाली लाइन में खींचता है या ईओएफ को हिट करता है तो यह पूरे छोटे प्रोग्राम को यूआईटी कर सकता है । लेकिन अगर यह !नहीं होता है और इसके बजाय सफलतापूर्वक स्टैक को आबाद करता है, तो यह Tफिर से कॉल करता है ।
  • d lm<M- Tएस्‍ट तब dस्‍टैक के शीर्ष को ऊपर उठाएगा और इसकी तुलना $max (जैसा कि संग्रहित है m) से करेगा । यदि mकम मूल्य है, dcतो Mमैक्रो को कॉल करें ।
  • s0 lm- Mबस स्टैक के शीर्ष को पॉप करता है और इसे डमी स्केलर पर डंप करता है 0- स्टैक को पॉप करने का सिर्फ एक सस्ता तरीका। यह भी वापस जाने से पहले lओड्स को ओड करता है ।mT
  • p- इसका मतलब है कि यदि mस्टैक के वर्तमान शीर्ष से कम है, तो mइसे ( dवैसे भी, इसका अपग्रेड) बदल देता है और यहां printed किया जाता है, अन्यथा यह नहीं होता है और जो कुछ भी इनपुट किया गया था वह pइसके बजाय रंगा हुआ है ।
  • s0- बाद में (क्योंकि pस्टैक पॉप नहीं करता है) हम स्टैक के शीर्ष को 0फिर से डंप करते हैं , और फिर ...
  • lTx- रिकर्सिवली load Tस्था एक बार फिर उसके बाद ई xफिर ecute यह।

तो आप अपने टर्मिनल पर इस छोटे से स्निपेट और अंतःक्रियात्मक प्रकार की संख्याओं को चला सकते हैं और आपके द्वारा 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कमांड के साथ सेट करते हैं, तो आप मनमानी परिशुद्धता के फ़्लोट्स को संभाल सकते हैं । और आप स्वतंत्र रूप से input या output मूलक को बदल सकते हैं - जो कभी-कभी उन कारणों के लिए उपयोगी हो सकता है जिनकी आप उम्मीद नहीं कर सकते हैं। उदाहरण के लिए:

echo 100000o 10p|dc
 00010

... जो पहले dc100000 तक आउटपुट मूलांक सेट करता है फिर 10 प्रिंट करता है।


3
+1 यह जानने के लिए कि दो बार पढ़ने के बाद क्या हुआ। इसमें देरी करने के लिए मेरा समय लेना पड़ेगा।
माइनिक्स

@Minix - meh - अगर आप इसे भ्रामक पाते हैं तो सबसे पुरानी यूनिक्स प्रोग्रामिंग भाषा में जाने की आवश्यकता नहीं है। हो सकता है कि बस dcथोड़ी देर में हर बार कुछ पंक्तियों को पाइप करें , हालांकि इसे अपने पैर की उंगलियों पर रखें।
15

1
@mikeserv यह मेरे लिए बहुत देर हो चुकी है। मुझे उम्मीद है कि भावी पीढ़ी मुझे एक सावधानी के रूप में ले जाएगी। हर जगह वर्ग कोष्ठक और अक्षर ...
Minix

@Minix - तुम्हारा क्या मतलब है? आप इसके लिए गए थे? बहुत अच्छा - dcएक चंचल जानवर है, लेकिन यह किसी भी यूनिक्स प्रणाली पर सबसे तेज़ और सबसे अजीब रूप से सक्षम आम उपयोगिता हो सकती है। जब युग्मित w / sedयह कुछ असाधारण चीजें कर सकता है। मैं इसके साथ खेल रहा हूं और ddहाल ही में इसलिए कि मैं उस राक्षसी की जगह ले सकता हूं readlineयहाँ मैं कर रहा हूँ कुछ सामान का एक छोटा सा नमूना है। एक कर revमें dcलगभग बच्चों का खेल है।
mikeserv

1
@Minix - सावधान डब्ल्यू / कोष्ठक, यद्यपि। एक स्ट्रिंग के भीतर एक वर्ग ब्रैकेट लगाने का कोई तरीका नहीं है - सबसे अच्छा आप कर सकते हैं [string]P91P93P[string]P। तो मेरे पास यह थोड़ा सा sedउपयोगी हो सकता है: sed 's/[][]/]P93]&[1P[/g;s/[]3][]][[][1[]//g'जो हमेशा वर्गों को एक स्ट्रिंग करीब ब्रैकेट के साथ सही ढंग से प्रतिस्थापित करना चाहिए, फिर ए P, फिर वर्ग के दशमलव एससीआई मूल्य और एक और P; फिर [स्ट्रिंग को जारी रखने के लिए एक खुला वर्ग ब्रैकेट। यदि आपने w / dcs स्ट्रिंग / संख्यात्मक रूपांतरण क्षमताओं के आसपास गड़बड़ कर दी है, लेकिन विशेष रूप से संयुक्त w / od- तो यह बहुत मज़ेदार हो सकता है।
26

88

यदि आप जानते हैं कि आप दो पूर्णांकों के साथ काम कर रहे हैं 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 ))

अच्छा जवाब। कृपया, एक मामूली मॉड: यह "> =" के लिए भी इस्तेमाल किया जा सकता है?
सोपालाजो डी एरियेरेज़

@SopalajodeArrierez मुझे पूरी तरह से यकीन नहीं है कि आपका क्या मतलब है। आप भी कर सकते हैं max=$(( a >= b ? a : b )), लेकिन परिणाम पूरी तरह से एक ही है - यदि ए और बी बराबर हैं, तो यह वास्तव में कोई फर्क नहीं पड़ता कि कौन सा वापस लौटा है। क्या आप यही पूछ रहे हैं?
डिजिटल ट्रॉमा

वास्तव में, धन्यवाद, DIgital ट्रॉमा। मैं बस सोच रहा था कि क्या बूलियन ऑपरेटर "=" यहां संभव था।
सोपालजो डे एरिएरेस

@SopalajodeArrierez if (( a >= b )); then echo a is greater than or equal to b; fi- यह है कि आप क्या मांग रहे हैं? (ध्यान दें (( ))यहाँ के बजाय का उपयोग करें $(( )))
डिजिटल ट्रामा

आह, हाँ, ठीक है। मैं अब समझता हूँ। मुझे शेल विस्तार के बारे में ज्यादा जानकारी नहीं है, इसलिए मैं आमतौर पर शर्तों के बीच उलझ जाता हूं। फिर से धन्यवाद।
सोपालाजो डी एरिएरेस

25

sortऔर यह headकर सकते हैं:

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

2
ध्यान दें कि यह O(n log(n))जबकि अधिकतम का एक कुशल कार्यान्वयन होगा O(n)। यह हमारा थोड़ा महत्व है n=2, हालांकि, दो प्रक्रियाओं के spawning बहुत बड़े उपरि हैं।
रेयान

1
जबकि सच है, @ ग्लेन-जैकमैन, मुझे यकीन नहीं है कि यह प्रश्न दिए गए मामले हैं। इसे करने के सबसे कुशल तरीके के लिए कोई अनुरोध नहीं किया गया था। मुझे लगता है कि सुविधा के बारे में सवाल अधिक था।
डेविड होल्ज़र

1
@DavidHoelzer - यहां दिए गए उत्तरों के बीच भी ऐसा करने का यह सबसे कारगर तरीका नहीं है। यदि संख्या सेट के साथ काम कर रहे हैं तो कम से कम एक अन्य उत्तर यहां है जो इससे अधिक कुशल है (परिमाण के आदेशों से) , और यदि केवल दो पूर्णांकों के साथ काम कर रहे हैं तो यहां एक और उत्तर है जो उससे अधिक कुशल है (परिमाण के आदेश द्वारा) । हालांकि यह सुविधाजनक है (लेकिन मैं व्यक्तिगत रूप से शेल ऐरे को छोड़ दूंगा)
15

1
इस प्रकार यह सरणियों के बिना किया जा सकता है:numbers="1 4 3 5 7 1 10 21 8"; echo $numbers | tr ' ' "\n" | sort -rn | head -n 1
ngreen

1
एक अधिक कुशल दृष्टिकोण शायद यह है:max=0; for x in $numbers ; do test $x -gt $max && max=$x ; done
ngreen

6

आप पूर्वनिर्धारित गणित कार्यों की लाइब्रेरी को परिभाषित कर सकते हैं bcऔर फिर कमांड लाइन में उनका उपयोग कर सकते हैं।

उदाहरण के लिए, एक पाठ फ़ाइल में निम्नलिखित को शामिल करें जैसे ~/MyExtensions.bc:

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

अब आप इसके bcद्वारा कॉल कर सकते हैं :

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

FYI करें, इस तरह के ऑनलाइन उपलब्ध नि: शुल्क गणित पुस्तकालय कार्य हैं

उस फ़ाइल का उपयोग करके, आप आसानी से अधिक जटिल कार्यों की गणना कर सकते हैं जैसे GCD:

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

यदि मैं गलत नहीं हूँ, तो ऐसे कार्यों को निष्पादन योग्य के साथ संकलित किया जा सकता है यदि आवश्यक हो। मुझे लगता है कि अधिकांश bcएस इस दिन के लिए केवल dcव्यय हैं, हालांकि, भले ही जीएनयूbc अब ऐसा नहीं है (लेकिन जीएनयू dcऔर जीएनयू bcअपने कोडबेस की एक विलक्षण मात्रा साझा करते हैं) । वैसे भी, यह यहाँ सबसे अच्छा जवाब हो सकता है।
15

शेल स्क्रिप्ट की फ़ाइल के भीतर इसे आसानी से कॉल करने के लिए, आप bcफ़ंक्शन कॉल के ठीक पहले फ़ंक्शन परिभाषा में पाइप कर सकते हैं । फिर दूसरी फाइल की जरूरत नहीं है :)
tanius

5

एक टिप्पणी के लिए बहुत लंबा:

जब आप इन चीजों को कर सकते हैं जैसे कि sort | headया sort | tailकॉम्बोस के साथ, यह संसाधन-और त्रुटि-हैंडलिंग-वार दोनों को अपनाने के बजाय लगता है। जहां तक ​​निष्पादन का संबंध है, कॉम्बो का अर्थ है दो प्रक्रियाओं को बस दो पंक्तियों की जांच करना। यह एक ओवरकिल का एक सा लगता है।

अधिक गंभीर समस्या यह है, कि ज्यादातर मामलों में आपको यह जानना होगा कि इनपुट समझदार है, जिसमें केवल संख्याएँ हैं। @ ग्लेनजैकमैन का समाधान बड़ी चतुराई से इसे हल करता है, क्योंकि printf %dइसे गैर-पूर्णांक पर बारफ करना चाहिए। यह या तो फ़्लोट्स के साथ काम नहीं करेगा (जब तक कि आप प्रारूप को निर्दिष्ट करने के लिए नहीं बदलते हैं %f, जहां आप गोल समस्याओं में भाग लेंगे)।

test $1 -gt $2 आपको यह संकेत देगा कि तुलना विफल रही या नहीं (2 की स्थिति से बाहर निकलने का मतलब है कि परीक्षण के दौरान कोई त्रुटि हुई थी। चूंकि यह आमतौर पर एक शेल-इन-बिल्ड है, इसलिए कोई अतिरिक्त प्रक्रिया नहीं है - हम सैकड़ों के आदेश की बात कर रहे हैं समय तेजी से निष्पादन। पूर्णांक के साथ ही काम करता है, हालांकि।

यदि आपको फ़्लोटिंग पॉइंट संख्याओं के एक जोड़े की तुलना करने की आवश्यकता होती है, तो दिलचस्प विकल्प हो सकता है bc:

define x(a, b) {
    if (a > b) {
       return (a);
    }
    return (b);
 }

test $1 -gt $2शेल में और इसके उपयोग के बराबर होगा :

max () { printf '
    define x(a, b) {
        if (a > b) {
           return (a);
        }
        return (b);
     }
     x(%s, %s)
    ' $1 $2 | bc -l
}

अभी भी printf | sort | head(दो संख्याओं के लिए) से लगभग 2.5 गुना तेज है ।

यदि आप जीएनयू एक्सटेंशन पर भरोसा कर सकते हैं bc, तो आप read()सीधे नंबर को पढ़ने के लिए फ़ंक्शन का उपयोग कर सकते हैं bc


मेरे विचार बिल्कुल - मैं बस इसे बाहर इस्त्री कर रहा था, लेकिन आपने मुझे इसे हरा दिया: dc -e "${max}sm[z0=?dlm<Mps0lTx]ST[?z0!=Tq]S?[s0lm]SMlTx"- ओह, सिवाय इसके कि dcपूरी बात करता है (इको को छोड़कर, हालांकि यह हो सकता है) - यह $maxया तो स्टड और प्रिंट्स या इनपुट नंबर पढ़ता है जिसके आधार पर छोटा है। वैसे भी, मैं वास्तव में इसे समझाने की परवाह नहीं करता हूं और आपका जवाब मेरे लिखने से बेहतर है। तो कृपया मेरा उत्थान हो।
mikeserv

@mikeserv वास्तव में एक समझाया dcस्क्रिप्ट होने वास्तव में अच्छा होगा, RPN कि अक्सर इन दिनों नहीं देखा जाता है।
पेट्रफ

रिवर्स पोलिश नोटेशन (उर्फ पोस्टफिक्स नोटेशन)। इसके अलावा अगर dcI / O खुद कर सकता है तो यह उससे भी अधिक सुरुचिपूर्ण होगा।
पेट्रफ

4

$ A और $ b का अधिक मूल्य प्राप्त करने के लिए इसका उपयोग करें:

[ "$a" -gt "$b" ] && $a || $b

लेकिन आपको इसके आसपास कुछ चाहिए, आपको संभवतः संख्या निष्पादित करने का मतलब नहीं है, इसलिए दो उपयोग "इको" का अधिक मूल्य प्रदर्शित करने के लिए

[ "$a" -gt "$b" ] && echo $a || echo $b

ऊपर एक शेल फ़ंक्शन में अच्छी तरह से फिट बैठता है, जैसे

max() {
   [ "$1" -gt "$2" ] && echo $1 || echo $2
}

चर में दो से अधिक असाइन करने के लिए, इस संशोधित संस्करण का उपयोग करें:

[ "$a" -gt "$b" ] && biggest=$a || biggest=$b

या परिभाषित फ़ंक्शन का उपयोग करें:

biggest=$( max $a $b )

फ़ंक्शन भिन्नता आपको बड़े करीने से इनपुट त्रुटि की जाँच करने का अवसर भी देती है।

अधिकतम दो दशमलव / फ़्लोटिंग पॉइंट नंबरों को वापस करने के लिए आप उपयोग कर सकते हैं awk

decimalmax() { 
   echo $1 $2 | awk '{if ($1 > $2) {print $1} else {print $2}}'; 
}

संपादित करें: इस तकनीक का उपयोग करके आप एक "सीमा" फ़ंक्शन बना सकते हैं जो आपके संपादन / नोट के अनुसार दूसरे तरीके से संचालित होता है। यह फ़ंक्शन दो के निचले हिस्से को लौटाएगा, जैसे:

limit() {
   [ "$1" -gt "$2" ] && echo $2 || echo $1
}

मुझे यूटिलिटी फ़ंक्शंस को एक अलग फ़ाइल में रखना पसंद है, इसे कॉल करें myprogram.funcsऔर इसे स्क्रिप्ट में निम्नानुसार उपयोग करें:

#!/bin/bash

# Initialization. Read in the utility functions
. ./myprogram.funcs

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

read number
echo $( limit $1 $number )

FWIW यह अभी भी वही करता है जो आपने किया था, और आपका संस्करण भले ही अधिक वर्बोज़ है, बस उतना ही कुशल है।

अधिक कॉम्पैक्ट रूप वास्तव में बेहतर नहीं है, लेकिन आपकी स्क्रिप्ट में अव्यवस्था को रोकता है। यदि आपके पास कई सरल हैं अगर-तो-और-फाई स्क्रिप्ट का विस्तार तेजी से निर्माण करता है।

यदि आप एक ही स्क्रिप्ट में कई बार बड़ी / छोटी संख्याओं के लिए चेक का फिर से उपयोग करना चाहते हैं, तो इसे एक फ़ंक्शन में रखें। फ़ंक्शन प्रारूप को डीबग करना और पुन: उपयोग करना आसान बनाता है और आपको आसानी से स्क्रिप्ट के उस हिस्से को बदलने की अनुमति देता है, उदाहरण के लिए एक गैर-पूर्णांक दशमलव संख्याओं को संभालने में सक्षम होने के लिए एक awk कमांड के साथ।

यदि यह एकल उपयोग का मामला है, तो इसे केवल इन-लाइन कोड करें।


4

आप एक फ़ंक्शन को इस प्रकार परिभाषित कर सकते हैं

maxnum(){
    if [ $2 -gt $1 ]
    then
        echo $2
    else
        echo $1
    fi
}

इसे कहते हैं maxnum 54 42और यह प्रतिध्वनियों 54। यदि आप चाहें तो फ़ंक्शन के अंदर सत्यापन जानकारी जोड़ सकते हैं (जैसे दो तर्क या संख्या के रूप में)।


अधिकांश गोले फ़्लोटिंग पॉइंट अंकगणित नहीं करते हैं। लेकिन यह पूर्णांकों के लिए काम करता है।
ओरियन

1
यह फ़ंक्शन अनावश्यक रूप से POSIX- असंगत है। बदलें function maxnum {करने के लिए maxnum() {है और यह कहीं अधिक गोले के लिए काम करेंगे।
चार्ल्स डफी

2

शेल स्क्रिप्ट से, किसी भी जावा सार्वजनिक स्थिर विधि (और उदाहरण के लिए Math.min () ) का उपयोग करने का एक तरीका है । लिनक्स पर बैश से:

. jsbInit
jsbStart 
A=2 
B=3 
C=$(jsb Math.min "$A" "$B")
echo "$C"

इसके लिए जावा शेल ब्रिज https://sourceforge.net/projects/jsbridge/ की आवश्यकता होती है

बहुत तेज़, क्योंकि विधि कॉल आंतरिक रूप से पाइप की जाती है ; कोई प्रक्रिया आवश्यक नहीं है।


0

ज्यादातर लोग बस sort -n input | head -n1(या पूंछ) करेंगे, यह अधिकांश स्क्रिप्टिंग स्थितियों के लिए पर्याप्त है। हालांकि, यह थोड़ा अनाड़ी है यदि आपके पास एक कॉलम के बजाय एक पंक्ति में नंबर हैं - आपको इसे एक उचित प्रारूप ( tr ' ' '\n'या कुछ समान) में प्रिंट करना होगा ।

शेल संख्यात्मक प्रसंस्करण के लिए बिल्कुल आदर्श नहीं हैं, लेकिन आप आसानी से कुछ अन्य कार्यक्रम में पाइप कर सकते हैं जो इसमें बेहतर है। आपकी अपनी पसंद के आधार पर, आप अधिकतम कॉल करते हैं dc(थोड़ा बहुत बाधित होता है, लेकिन यदि आप जानते हैं कि आप क्या कर रहे हैं, तो यह ठीक है - mikeserv का उत्तर देखें), या awk 'NR==1{max=$1} {if($1>max){max=$1}} END { print max }'। या संभवतः perlया pythonयदि आप पसंद करते हैं। एक समाधान (यदि आप कम ज्ञात सॉफ़्टवेयर स्थापित करने और उपयोग करने के लिए तैयार हैं) ised(विशेषकर यदि आपका डेटा एक पंक्ति में है: तो आपको बस करने की आवश्यकता है ised --l input.dat 'max$1')।


क्योंकि तुम दो नंबर मांग रहे हो, यह सब ओवरकिल है। यह पर्याप्त होना चाहिए:

python -c "print(max($j,$k))"

1
यदि आप उपयोग करते हैं तो बेहतर हो सकता है sys.argv:python2 -c 'import sys; print (max(sys.argv))' "$@"
muru

1
वे तर्क जो sort + headओवरकिल हैं, लेकिन pythonगणना नहीं करते हैं।
15

लाइन के ऊपर के सभी तरीके संख्याओं के विशाल सेट को संभालने के लिए डिज़ाइन किए गए हैं और स्पष्ट रूप से इस तरह के उपयोग (पाइप या फ़ाइल से पढ़ना) का सुझाव देते हैं। 2 तर्कों के लिए न्यूनतम / अधिकतम वह प्रश्न है जो अलग तरह से महसूस होता है - यह एक धारा के बजाय एक फ़ंक्शन के लिए कहता है। मेरा मतलब सिर्फ यह था कि स्ट्रीम अप्रोच ओवरकिल है - आपके द्वारा उपयोग किया जाने वाला टूल मनमाना है, मैंने सिर्फ pythonइसलिए इस्तेमाल किया क्योंकि यह साफ-सुथरा है।
ओरियन

मैं इस सुझाए गए समाधान को खाने वाला कहूंगा , लेकिन ऐसा इसलिए हो सकता है क्योंकि मैं एक बहुत pythonबड़ा व्यक्ति हूं (या क्योंकि इसके लिए कांटा और अतिरिक्त विशाल दुभाषिया की आवश्यकता नहीं है) । या शायद दोनों।
15

अगर मैं जानता था कि वे पूर्णांक थे @ mikeserv मैं भी इस्तेमाल करेंगे। इन सभी समाधानों का मैंने उल्लेख किया है कि यह अनुमान लगाया जा रहा है कि संख्या फ़्लोट हो सकती है - बैश फ़्लोटिंग पॉइंट नहीं करता है और जब तक कि ज़श आपका मूल शेल नहीं है, आपको एक कांटा (और संभवतः एक चाकू) की आवश्यकता होगी
ओरियन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.