我有一个文件abc,其内容如下:
Bob 23
Jack 44
Rahul 36
Run Code Online (Sandbox Code Playgroud)
我也有一个shell脚本,可以在这里添加所有数字。选取这些数字的特定行是-
while read line
do
num=echo ${line#* }
sum=`expr $sum + $num`
count=`expr $count + 1`
done< "$readfile"
Run Code Online (Sandbox Code Playgroud)
我以为代码只是从文件中获取最后一个字段,但事实并非如此。如果我像修改文件
Bob 23 12
Jack 44 23
Rahul 36 34
Run Code Online (Sandbox Code Playgroud)
同一脚本因语法错误而失败。
注意:我知道还有其他获取字段值的方法,但是我想知道这是如何工作的。
The syntax ${line#* } will skip the shortest string from the beginning till it finds a space and returns the rest. It worked fine when you had just 2 columns. But the same will not work when 3 columns are present as it will return you the last 2 column values which when you use it in the sum operator will throw you an error. To explain that, just imagine
str='foo bar'
printf '%s\n' "${str#* }"
bar
Run Code Online (Sandbox Code Playgroud)
but imagine the same for 3 fields
str='foo bar foobar'
printf '%s\n' "${str#* }"
bar foobar
Run Code Online (Sandbox Code Playgroud)
To fix that use the parameter expansion syntax of "${str##* }" to skip the longest sub-string from beginning. To fix your script for the example with 3 columns, I would use a script as below.
This does a simple input redirection on the file and uses the read command with the default IFS value which is a single white space. So I'm getting only the 3rd field on each line (even if it has multiple fields), the _ mark the fields I'm skipping. You could also have some variables as place-holders and use their value in the scripts also.
declare -i sum
while read -r _ _ value _ ; do
((sum+=value)
done < file
printf '%d\n' "$sum"
Run Code Online (Sandbox Code Playgroud)
See Bash - Parameter Expansion (Substring removal) to understand more.
You could also use the PE syntax ${line##* } as below,
str='foo bar'
printf '%s\n' "${str#* }"
bar
Run Code Online (Sandbox Code Playgroud)
[Not relevant to the current question]
If you just want the sum to be computed and not specifically worried about using bash script for this. You can use a simple Awk command to sum up values in 3rd column as
awk '{sum+=$3}END{print sum}' inputfile
Run Code Online (Sandbox Code Playgroud)