Antoshjke
Antoshjke

Reputation: 462

Bash nested loop readline from file

I am stuck with the problem. Basically I have two different text files one with questions, another one with answers. Loop reads the first question from the file and waits for input from the user, then compares input with first line in other text file. But it goes thru the whole second file and compares all the lines.

There is a code.

#!/bin/bash

wrong=0
right=0

while  IFS='' read -r question || [[ -n "$question" ]]; 
 do
 echo "$question"
 read input </dev/tty
 while IFS='' read -r answer || [[ -n "$answer" ]];
 do
  if  [[ $answer == *"$input"* ]]
  then
  ((right+=1))
  else
  ((wrong+=1))
 fi
 done < answers.txt
done < file.txt

echo "Wrong answers: $wrong"
echo "Right answers: $right"

What it does at the moment and takes first line from questions, compares with every single line in answers and goes to another question. But I need nested loop only compare with first line and move one to another question and so on.

Upvotes: 2

Views: 828

Answers (2)

Srinivas Balaji
Srinivas Balaji

Reputation: 21

Antoshije, 

You would need to break the loop . try the below

#!/bin/bash

let wrong=0
let right=0


function check_ans
{
in_ans=$1
cat answers.txt | while read ans
do
    if [[ "$in_ans" == "$ans" ]]
        then
        echo "correct"
        break;
    fi
done
}

cat questions.txt | while read question
do
    echo $question
    read ans
    c_or_w=$(check_ans "$ans")
    if [[ $c_or_w == "correct" ]]
    then
        right=$((right+1))
    else
        wrong=$((wrong+1))  
    fi      
done
echo "Wrong answers: $wrong"
echo "Right answers: $right"

Upvotes: 0

kojiro
kojiro

Reputation: 77107

Since you're expecting input from a tty, I'm going to assume the files aren't terribly large, memory-wise. Therefore, reading them entirely into memory seems feasible, and a neat way to avoid dealing with the problem you have:

#!/bin/bash

wrong=0
right=0

# Use mapfile to read the files into arrays, one element per line
mapfile -t questions < questions.txt
mapfile -t answers < answers.txt

# Loop over the indices of the questions array
for i in "${!questions[@]}"; do
    question="${questions[i]}"
    [[ $question ]] || continue

    # Look up the answer with the same index as the question
    answer="${answers[i]}"

    # Use read -p to output the question as a prompt
    read -p "$question " input
    if  [[ $answer = *"$input"* ]]
    then
        ((right++))
    else
        ((wrong++))
    fi
done

echo "Wrong answers: $wrong"
echo "Right answers: $right"

Upvotes: 3

Related Questions