我有一行数字,我希望能够逐个处理它们。对于前者
3829 4837 3729 2874 3827
我希望能够获得总和,最大数量,任何东西。但我不知道如何让每个数字来处理它。我会REAAAAALLLLLLLLLLY喜欢坚持使用纯粹的bash,我不介意在bash中使用复杂的解决方案。但如果awk绝对必要,我会用它。我不想使用sed。
我想我可以这样做:
max= cut -d" " -f1
in line L cut -d" " -f$(loop index)
#check for max
我很困惑。
编辑: 感谢您的回答,我看到了一些我从未在bash中看到的新事物,我已经准备好更多地探索它们了。我收到了我寻求的信息甚至更多! :)
答案 0 :(得分:2)
如果要逐个处理进程号,请利用 shell分词:
numbers="3829 4837 3729 2874 3827"
for n in $numbers; do
# do something with "$n"
done
SUM
:
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
或者,如果你想要一个带有一些shell技巧的全局SUM
:
$ 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
答案 1 :(得分:2)
如果你有一个字符串中的数字列表,按照以下方式处理它们是最安全的分割和迭代方法(同时避免全局扩展或其他副作用):
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。
答案 2 :(得分:1)
这里有两种方法可以将一串单词拆分成一个可以迭代的结构:
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
使用实际的array
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