Bash while 循环完成 < $1

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43600071/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 16:04:00  来源:igfitidea点击:

Bash while loop with done < $1

bashwhile-loop

提问by themightyscot

I'm a bit confused by the done < $1notation.

我对done < $1符号有点困惑。

I'm trying to write a program "sumnums" that reads in a file called "nums" that has a couple rows of numbers. Then it should print out the rows of the numbers followed by a sum of all the numbers.

我正在尝试编写一个程序“sumnums”,该程序读取一个名为“nums”的文件,该文件包含几行数字。然后它应该打印出数字的行,然后是所有数字的总和。

Currently I have:

目前我有:

#!/bin/bash
sum=0;
while read myline
do  
  echo "Before for; Current line: \"$myline\""
done
for i in $myline; do  
  sum=$(expr $sum + $i)
done <     
echo "Total sum is: $sum"

and it outputs the list of the numbers from nums correctly then says ./sumnums: line 10: $1: ambiguous redirect, then outputs Total sum is: 0.

它从 nums 正确./sumnums: line 10: $1: ambiguous redirect输出数字列表,然后说 ,然后输出Total sum is: 0.

So somehow it isn't adding. How do I rearrange these lines to fix the program and get rid of the "ambiguous redirect"?

所以不知何故它没有添加。如何重新排列这些行以修复程序并摆脱“模糊重定向”?

回答by Charles Duffy

Assuming your filename is in $1(that is, that your script was called with ./yourscript nums):

假设您的文件名在$1(也就是说,您的脚本是用 调用的./yourscript nums):

#!/bin/bash

[[  ]] || set -- nums  ## use  if already set; otherwise, override with "nums"

sum=0
while read -r i; do      ## read from stdin (which is redirected by < for this loop)
  sum=$(( sum + i ))     ## ...treat what we read as a number, and add it to our sum
done <""               ## with stdin reading from  for this loop
echo "Total sum is: $sum"

If $1doesn't contain your filename, then use something that doescontain your filename in its place, or just hardcode the actual filename itself.

如果$1不包含您的文件名,然后使用一些包含您的文件名在其位,或只是硬编码的实际文件名本身。

Notes:

笔记:

  • <"$1"is applied to a while readloop. This is essential, because readis (in this context) the command that actually consumes content from the file. It canmake sense to redirect stdin to a forloop, but only if something inside that loop is reading from stdin.
  • $(( ))is modern POSIX sh arithmetic syntax. expris legacy syntax; don't use it.
  • <"$1"应用于while read循环。这是必不可少的,因为read(在这种情况下)是实际使用文件内容的命令。它可以是有意义的重定向标准输入到一个for循环,但只有在该循环里面的东西是从标准输入读取。
  • $(( ))是现代 POSIX sh 算术语法。expr是遗留语法;不要使用它。

回答by karakfa

awkto the rescue!

awk来救援!

awk '{for(i=1;i<=NF;i++) sum+=$i} END{print "Total sum is: " sum}' file

bashis not the right tool for this task.

bash不是执行此任务的正确工具。