获取 Linux Shell 中最大和最小值的方法有多种可能性。

huangapple go评论94阅读模式
英文:

How to get max and min values in linux shell with multiple possibilities?

问题

这个shell脚本获取了最大和最小值,但我想在有重复值时获取这些值以及相关的学生。

代码:

  1. #!/bin/sh
  2. Notamax=0
  3. Notamin=0
  4. alumneMax=''
  5. alumneMin=''
  6. while IFS=';' read alumne nota
  7. do
  8. (( nota > Notamax )) && Notamax=$nota alumneMax="$alumneMax $alumne $nota"
  9. (( nota < Notamin || Notamin == 0)) && Notamin=$nota alumneMin="$alumneMin $alumne $nota"
  10. done < notas.txt
  11. echo "Max:$alumneMax"
  12. echo "Min:$alumneMin"

notas.txt

  1. pepe;5
  2. marcos;7
  3. marta;70
  4. luis;70
  5. ana;5

期望输出

  1. Max: marta 70, luis 70
  2. Min: pepe 5, ana 5

你可以使用上述修改后的代码来实现期望的输出。

英文:

This shell script gets me the max and min values, but I would like to get those values and the associated students when there are repeats.

Code:

  1. #!/bin/sh
  2. Notamax=0
  3. Notamin=0
  4. alumneMax=&#39;&#39;
  5. alumneMin=&#39;&#39;
  6. while IFS=&quot;;&quot; read alumne nota
  7. do
  8. (( nota &gt; Notamax )) &amp;&amp; Notamax=$nota alumneMax=$alumne
  9. (( nota &lt; Notamin || Notamin == 0)) &amp;&amp; Notamin=$nota alumneMin=$alumne
  10. done &lt;notas.txt
  11. echo &quot;Nota maxima $Notamax ** Alumnos con nota maxima: $alumneMax&quot;
  12. echo &quot;Nota minima $Notamin ** Alumnos con nota minima: $alumneMin&quot;

notas.txt

  1. pepe;5
  2. marcos;7
  3. marta;70
  4. luis;70
  5. ana;5

Actual output

  1. Nota maxima 70 ** Alumnos con nota maxima: marta
  2. Nota minima 5 ** Alumnos con nota minima: pepe

Desired output

  1. Max: marta 70, luis 70
  2. Min: pepe 5, ana 5

How could I achieve it?

答案1

得分: 5

This is both easier and more versatile with Awk. See also Bash while read loop extremely slow compared to cat, why?

  1. $2==max { maxa = maxa ", " $1 " " $2 }
  2. $2==min { mina = mina ", " $1 " " $2 }
  3. $2>max { max = $2; maxa = $1 " " $2 }
  4. $2<min { min = $2; mina = $1 " " $2 }
  5. END { print "Max:", maxa
  6. print "Min:", mina }' notas.txt

Your output format is somewhat noisy; I would personally prefer a less redundant and more machine-readable display.

The awk tag info page has links to basic learning resources. Learning the fundamentals of the language is quick and easy (give it an hour and you'll already have a good idea).

英文:

This is both easier and more versatile with Awk. See also Bash while read loop extremely slow compared to cat, why?

  1. awk -F &#39;;&#39; &#39;NR==1 { min = max = $2; mina = maxa = $1 &quot; &quot; $2; next }
  2. $2==max { maxa = maxa &quot;, &quot; $1 &quot; &quot; $2 }
  3. $2==min { mina = mina &quot;, &quot; $1 &quot; &quot; $2 }
  4. $2&gt;max { max = $2; maxa = $1 &quot; &quot; $2 }
  5. $2&lt;min { min = $2; mina = $1 &quot; &quot; $2 }
  6. END { print &quot;Max:&quot;, maxa
  7. print &quot;Min:&quot;, mina }&#39; notas.txt

Your output format is somewhat noisy; I would personally prefer a less redundant and more machine-readable display.

The awk tag info page has links to basic learning resources. Learning the fundamentals of the language is quick and easy (give it an hour and you'll already have a good idea).

答案2

得分: 3

以下是翻译好的部分:

  1. 如果我们需要坚持使用 bash ...

对OP目前的代码做一些更改:

  1. NotaMax=0
  2. NotaMin=0
  3. while IFS=";" read -r alumne nota
  4. do
  5. (( nota == NotaMax )) && alumneMax="${alumneMax}, ${alumne} ${NotaMax}"
  6. (( nota > NotaMax )) && NotaMax=$nota alumneMax="Max: ${alumne} ${NotaMax}"
  7. (( nota == NotaMin )) && alumneMin="${alumneMin}, ${alumne} ${NotaMin}"
  8. (( nota < NotaMin || NotaMin == 0 )) && NotaMin=$nota alumneMin="Min: ${alumne} ${NotaMin}"
  9. done < notas.txt
  10. echo "${alumneMax}"
  11. echo "${alumneMin}"
  1. 使用一对数组和匹配的 namerefs(namerefs 需要 bash 4.2+):
  1. NotaMax=0
  2. NotaMin=0
  3. while IFS=";" read -r alumne nota
  4. do
  5. (( nota == NotaMax )) && alumneMax+=("${alumne}")
  6. (( nota > NotaMax )) && NotaMax=$nota alumneMax=("${alumne}")
  7. (( nota == NotaMin )) && alumneMin+=("${alumne}")
  8. (( nota < NotaMin || NotaMin == 0)) && NotaMin=$nota alumneMin=("${alumne}")
  9. done < notas.txt
  10. for op in Max Min
  11. do
  12. pfx="$op: "
  13. declare -n oparr="alumne${op}"
  14. declare -n opval="Nota${op}"
  15. for alumne in "${oparr[@]}"
  16. do
  17. printf "%s%s %s" "$pfx" "$alumne" "$opval"
  18. pfx=", "
  19. done
  20. echo ""
  21. done

这两者都会生成:

  1. Max: marta 70, luis 70
  2. Min: pepe 5, ana 5
英文:

If we need to stick with bash ...

Making a few changes to OP's current code:

  1. NotaMax=0
  2. NotaMin=0
  3. while IFS=&quot;;&quot; read -r alumne nota
  4. do
  5. (( nota == NotaMax )) &amp;&amp; alumneMax=&quot;${alumneMax}, ${alumne} ${NotaMax}&quot;
  6. (( nota &gt; NotaMax )) &amp;&amp; NotaMax=$nota alumneMax=&quot;Max: ${alumne} ${NotaMax}&quot;
  7. (( nota == NotaMin )) &amp;&amp; alumneMin=&quot;${alumneMin}, ${alumne} ${NotaMin}&quot;
  8. (( nota &lt; NotaMin || NotaMin == 0 )) &amp;&amp; NotaMin=$nota alumneMin=&quot;Min: ${alumne} ${NotaMin}&quot;
  9. done &lt; notas.txt
  10. echo &quot;${alumneMax}&quot;
  11. echo &quot;${alumneMin}&quot;

Using a pair of arrays and matching namerefs (namerefs require bash 4.2+):

  1. NotaMax=0
  2. NotaMin=0
  3. while IFS=&quot;;&quot; read -r alumne nota
  4. do
  5. (( nota == NotaMax )) &amp;&amp; alumneMax+=(&quot;${alumne}&quot;)
  6. (( nota &gt; NotaMax )) &amp;&amp; NotaMax=$nota alumneMax=(&quot;${alumne}&quot;)
  7. (( nota == NotaMin )) &amp;&amp; alumneMin+=(&quot;${alumne}&quot;)
  8. (( nota &lt; NotaMin || NotaMin == 0)) &amp;&amp; NotaMin=$nota alumneMin=(&quot;${alumne}&quot;)
  9. done &lt; notas.txt
  10. for op in Max Min
  11. do
  12. pfx=&quot;$op: &quot;
  13. declare -n oparr=&quot;alumne${op}&quot;
  14. declare -n opval=&quot;Nota${op}&quot;
  15. for alumne in &quot;${oparr[@]}&quot;
  16. do
  17. printf &quot;%s%s %s&quot; &quot;$pfx&quot; &quot;$alumne&quot; &quot;$opval&quot;
  18. pfx=&quot;, &quot;
  19. done
  20. echo &quot;&quot;
  21. done

Both of these generate:

  1. Max: marta 70, luis 70
  2. Min: pepe 5, ana 5

huangapple
  • 本文由 发表于 2023年5月15日 00:19:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76248531.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定