在bash中处理一行分隔的数字



我有一行数字,我希望能够逐一处理它们。例如

3829 4837 3729 2874 3827 

我想要得到和,最大的数,任何数。但我不确定如何让每个数字处理它。我真的很喜欢使用纯bash,我不介意在bash中使用复杂的解决方案。但如果awk是绝对必要的,我会使用它。我不想用sed

我想我可以这样做:

max= cut -d" " -f1
in line L cut -d" " -f$(loop index) 
#check for max

我困惑。

编辑:谢谢你的回答,我在bash中看到了一些我从未见过的新东西,我已经准备好更多地探索它们。我收到了我想要的信息,甚至更多!:)

如果您想逐个处理进程号,请利用shell分词:

numbers="3829 4837 3729 2874 3827"
 for n in $numbers; do
     # do something with "$n"
done

SUM:

numbers="3829 4837 3729 2874 3827"
echo $((${numbers// /+}))

numbers="3829 4837 3729 2874 3827"
for n in $numbers; do
     ((sum+=n))
done
echo $sum

LARGEST:

numbers="3829 4837 3729 2874 3827"
for n in $numbers; do
     ((max<n)) && max=$n
done
echo $max

或者,如果你想要一个全局的SUM和一些shell技巧:

$ tr ' ' '+' <<< '3829 4837 3729 2874 3827' | bc                                 
19096 

$ awk '{$1=$1; print}' OFS=+ <<< '3829 4837 3729 2874 3827' | bc
19096

$ echo  '3829 4837 3729 2874 3827' |
    awk '{for (i=1; i<=NF; i++) c+=$i} {print c}'
19096

如果字符串中有一个数字列表,那么按照以下方式处理它们是分割和迭代的最安全方法(同时避免全局扩展或其他副作用):

max=0
read -r -a number_array <<<"$numbers"
for number in "${number_array[@]}"; do
  if (( number > max )) ; then
    max=number
  fi
done    

如果从文件中读取,可以进行简单的修改(参见http://mywiki.wooledge.org/BashFAQ/001获取读取文件的最佳实践):

max=0
while read -r -a numbers; do
  for number in "${numbers[@]}"; do
    if (( number > max )) ; then
      max=number
    fi
  done
done <input-file

如果分隔符是其他内容,则可以适当地设置IFS。例如,如果用逗号分隔:

while IFS=, read -r -a numbers; do

注意,当你的值被限制为数字时,这里给出的最佳实践并不重要。但是,如果输入数据中有*,则只需运行

for number in $numbers; do

$numbers字符串中的*将被替换为当前目录中的文件列表。别那样做。

最后一点说明——bash没有内置对浮点数学的支持。如果需要浮点运算,请参见http://mywiki.wooledge.org/BashFAQ/022。

这里有几种方法可以将一串单词拆分为一个可以遍历的结构:

使用位置参数

numbers="3829 4837 3729 2874 3827"
set -- $numbers
sum=0
for n in "$@"; do
    # do something with $n
    (( sum += n ))
done
average=$(( sum / $# ))   # integer division only

使用实际的数组

numbers="3829 4837 3729 2874 3827"
nums=( $numbers )
sum=0
for n in "${nums[@]}"; do
    # do something with $n
    (( sum += n ))
done
average=$(( sum / ${#nums[@]} ))   # integer division only

最新更新