我有一个包含数千个数字的文件,每个数字都在自己的行上:
34
42
11
6
2
99
...
我想写一个脚本,它将打印文件中所有数字的总和。我有一个解决办法,但不是很有效。(运行需要几分钟。)我在寻找一个更有效的解决方案。有什么建议吗?
我有一个包含数千个数字的文件,每个数字都在自己的行上:
34
42
11
6
2
99
...
我想写一个脚本,它将打印文件中所有数字的总和。我有一个解决办法,但不是很有效。(运行需要几分钟。)我在寻找一个更有效的解决方案。有什么建议吗?
当前回答
这是直接的Bash:
sum=0
while read -r line
do
(( sum += line ))
done < file
echo $sum
其他回答
我不能只是路过……下面是我的Haskell俏皮话。它实际上是相当可读的:
sum <$> (read <$>) <$> lines <$> getContents
不幸的是,没有ghci -e来运行它,所以它需要main函数、打印和编译。
main = (sum <$> (read <$>) <$> lines <$> getContents) >>= print
为了澄清,我们读取整个输入(getContents),按行分割,读取为数字和和。<$>是fmap操作符-我们使用它而不是通常的函数应用程序,因为这一切都发生在IO中。Read需要一个额外的fmap,因为它也在列表中。
$ ghc sum.hs
[1 of 1] Compiling Main ( sum.hs, sum.o )
Linking sum ...
$ ./sum
1
2
4
^D
7
下面是一个奇怪的升级,让它与浮动一起工作:
main = ((0.0 + ) <$> sum <$> (read <$>) <$> lines <$> getContents) >>= print
$ ./sum
1.3
2.1
4.2
^D
7.6000000000000005
另一个是为了好玩
sum=0;for i in $(cat file);do sum=$((sum+$i));done;echo $sum
或者再来一次
s=0;while read l; do s=$((s+$l));done<file;echo $s
但awk解决方案可能是最好的,因为它最紧凑。
在去:
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
sum := int64(0)
for scanner.Scan() {
v, err := strconv.ParseInt(scanner.Text(), 10, 64)
if err != nil {
fmt.Fprintf(os.Stderr, "Not an integer: '%s'\n", scanner.Text())
os.Exit(1)
}
sum += v
}
fmt.Println(sum)
}
sed ':a;N;s/\n/+/;ta' file|bc
Bash变体
raw=$(cat file)
echo $(( ${raw//$'\n'/+} ))
$ wc -l file
10000 file
$ time ./test
323390
real 0m3,096s
user 0m3,095s
sys 0m0,000s
这里发生了什么?读取一个文件的内容到$raw var中,然后通过将所有新行更改为“+”来从该var创建数学语句