【问题标题】:Bash - getting MAX value from a list of integersBash - 从整数列表中获取最大值
【发布时间】:2018-04-15 16:14:53
【问题描述】:

此脚本将 cvs 列表分成三列。 我们专注于“名称”列。我想找出字符最多的名字。一旦找到字符最多的名称,我想将其分配给一个变量。

#!/bin/bash
for i in $(cat homeaway.txt )
do
echo $i | while IFS=, read -r area name host
do
        maxLength=0
        length=${#name}
        if [ $length -gt $maxLength ] ; then
            maxLength=$length
        else
           :
        fi
        printf "%s\n" $maxLength

      done
done

脚本说 - 英文 - 如果长度大于 maxlength,则将长度设置为 maxLength,如果不是,则不执行任何操作。 其中字符最多的区域字符串是“script_name_12345678999999”,共有 26 个字符。当脚本读取所有字符时,$maxLength 应该返回 26。

__DATA__
HOME,script_name_12345,USAhost.com   
AWAY,script_name_123,USAhost.com
HOME,script_name_1,EUROhost.com
AWAY,script_name_123,USAhost.com
HOME,script_name_123456,EUROhost.com
AWAY,script_name_12345678999999,USAhost.com
HOME,script_name_1234,USAhost.com
AWAY,script_name_1234578,USAhost.com
HOME,script_name_12,EUROhost.com
AWAY,script_name_123456789,USAhost.com

一旦脚本达到包含 26 个字符的区域值,它应该停止将任何内容分配给 $maxLength。 相反,它返回每个字符串长度的列表,我不知道零是如何进入这里的

casper@casper01.com $ ./length_test.sh
17
0   ### how does the zero get in here ?
15
13
15
18
26  ###script_name_12345678999999
16
19
14
21

【问题讨论】:

  • maxLength=0 每个循环?
  • 循环中的每次迭代都不打算让 maxLength 归零。我以为我只是在初始化它。

标签: bash list while-loop max


【解决方案1】:

my_command | sort -n | tail -1

对命令的输出进行数字和升序排序。获取结果列表中的最后一个元素。

【讨论】:

    【解决方案2】:

    在 GNU/Linux 上,您也可以一次性完成。如果文件data有你的记录:

    cut -d, -f2 < data | wc -L
    

    英文:

    • 提取第二列,使用“,”作为字段分隔符
    • 打印最长行的长度

    【讨论】:

    • 这是一段非常引人注目的编程
    • 我认为这展示了 shell 的优雅和强大
    • 我以为我们想从整数列表中找到最大值?如果所有值的位数相同,这不起作用,对吧?
    • 另外,我认为wc -L 会打印最大行长。所以它只会给你最大数字的位数(即如果 400 是你的最大数字,wc -L 给你 3)
    • 啊,好吧。我专注于“我想要整数列表中的最大整数”
    【解决方案3】:

    您的循环有点不稳定(技术术语),您在循环的每次迭代中将maxLength 重置为零。你想要的东西更像:

    #!/bin/bash
    
    fn="${1:-/dev/stdin}"   ## read from file given as 1st argument (default stdin)
    
    test -r "$fn" || {      ## validate file is readable 
        printf "error: file not readable '%s'.\n" "$fn"
        exit 1
    }
    
    declare -i maxlength=0  ## set maxlength before loop
    maxname=
    
    while IFS=, read -r area name host
    do
        test -n "$name" || continue            ## if name not set get next line
        len=${#name}
        if [ "$len" -gt "$maxlength" ]; then   ## test length against max
            maxlength=$len                     ## update max if greater
            maxname="$name"                    ## save name in maxname
        fi
    done <"$fn"                                ## feed loop by redirecting file
    
    printf "maxname: %s  (len: %d)\n" "$maxname" "$maxlength"
    

    使用/输出示例

    $ bash maxnm.sh <dat/maxnm.txt
    maxname: script_name_12345678999999  (len: 26)
    

    查看一下,如果您还有其他问题,请告诉我。

    【讨论】:

      【解决方案4】:

      如果你会使用 awk 就很容易

      既然你说:

      此脚本将 cvs 列表分成三列。我们专注 在“名称”列上。我想发现拥有最多的名字 字符

      awk -F, '{l=length($2)}l>max{max=l; name=$2}END{print name, max}' infile
      

      这是测试结果:

      $ cat infile
      HOME,script_name_12345,USAhost.com   
      AWAY,script_name_123,USAhost.com
      HOME,script_name_1,EUROhost.com
      AWAY,script_name_123,USAhost.com
      HOME,script_name_123456,EUROhost.com
      AWAY,script_name_12345678999999,USAhost.com
      HOME,script_name_1234,USAhost.com
      AWAY,script_name_1234578,USAhost.com
      HOME,script_name_12,EUROhost.com
      AWAY,script_name_123456789,USAhost.com
      
      $ awk -F, '{l=length($2)}l>max{max=l; name=$2}END{print name, max}' infile
      script_name_12345678999999 26
      

      如果您只想将最大长度的 script_name 获取到变量,则只需打印变量名,然后将其包含在 $(....) 中,如下所示

      $ myvar=$( awk -F, '{l=length($2)}l>max{max=l; name=$2}END{print name}' infile )
      $ echo "$myvar"
      $ script_name_12345678999999
      

      【讨论】:

        猜你喜欢
        • 2017-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-28
        • 2016-01-21
        • 2020-11-28
        • 2014-01-16
        • 1970-01-01
        相关资源
        最近更新 更多