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

次に、生徒のタイプを出力した後、テキスト ファイルの 3 列目のすべての数値を合計したいのですが、うまくいきませんでした

#!/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 に答える