0

文本文件

学生.txt

jane,good,3
bob,bad,2.6
annie,good,2.8
dan,bad,2

首先我尝试打印所有成功的好学生

#!/bin/bash

while IFS=, read -r -a array; do
   [[  "${array[1]}" == "good"  ]] || continue
   printf "%s \n" "${array[0]}" is a ${array[1]} student"
   done  <  "student.txt"

输出

jane is a good student
annie is a good student

接下来我也想在打印student的类型后总结文本文件中第三列的所有数字,没有成功

#!/bin/bash
while IFS=, read -r -a array; do
   [[  "${array[1]}" == "good"  ]] || continue
   printf "%s \n" "${array[0]}" is a ${array[1]} student"

   for n in "${array[2]}"; do
      total=$( "$total +=$n" | bc )
      echo $total
   done
done  <  "student.txt"

输出

jane is a good student
+=3: command not found
annie is a good student
+=2.8: command not found

预期产出

jane is a good student
annie is a good student
total = 5.8

由于我是 bash 脚本的新手,我需要向你们寻求帮助。

哦,另一件事,我似乎无法充分利用 awk 实用程序。

即使我尝试了一个使用 awk 的简单语句,
例如

awk -F","  "{print $1}"  "student.txt"

没错,如果我没有错,它应该返回这样的东西

输出

good
bad
good
bad

但相反,它返回了我不知道为什么的文本文件的整个值

我对 awk -F","{print $1}" "student.txt" 的输​​出

jane,good,3
bob,bad,2.6
annie,good,2.8
dan,bad,2

所以我想任何使用 awk 方法的建议都没有了。

4

3 回答 3

3

试试这个单行:

awk -F, '$2=="good"{print $1" is good";s+=$3}END{print "total:"s}' file

输出:

jane is good
annie is good
total:5.8
于 2013-10-30T09:30:36.180 回答
0

纯重击。模拟丢失的浮点运算。

total=0
while IFS=, read -r -a array
do
  [[  "${array[1]}" == "good"  ]] || continue
  printf "%s \n" "${array[0]} is a ${array[1]} student"

  [[ "${array[2]}" =~ ([0-9])(\.([0-9]))? ]]
  (( total += 10*${BASH_REMATCH[1]} + ${BASH_REMATCH[3]:-0} ))
done  <  "student.txt"

printf "total = %d.%d" $((total/10)) $((total%10)

输出

jane is a good student 
annie is a good student 
total = 5.8
于 2013-10-30T16:59:52.437 回答
0

这应该这样做(否awk):

#!/bin/bash
total=0
while IFS=, read -r -a array; do
    [[  "${array[1]}" == "good"  ]] || continue
    printf "%s is a %s student\n" "${array[@]:0:2}"
    total=$(bc <<< "$total+${array[2]}")
done < "student.txt"
echo "$total"

现在,这bc为每个学生分叉。相反,您可以这样滥用 IFS:

#!/bin/bash
total=()
while IFS=, read -r -a array; do
    [[  "${array[1]}" == "good"  ]] || continue
    printf "%s is a %s student\n" "${array[@]:0:2}"
    total+=( "${array[2]}" )
done < "student.txt"
# Abusing IFS, I know what I'm doing!
IFS="+" bc <<< "${total[*]}"

:)

或者,没有 IFS 滥用,也没有将数据保存在数组中的内存中:

#!/bin/bash
{
    while IFS=, read -r -a array; do
        [[  "${array[1]}" == "good"  ]] || continue
        printf >&2 "%s is a %s student\n" "${array[@]:0:2}"
        printf "%s+" "${array[2]}"
    done < "student.txt"
    echo "0"
} | bc

评论。在最后一种情况下,我们必须人为地添加一个 0。

锻炼。使用dc而不是bc.

于 2013-10-30T10:37:36.540 回答