Reading in two lines at once from a text file

Hello everyone,

I have thought about this for quite some time and know what I want to do but am having some trouble at it. I have a text file filled with numbers like this, there are more in the file obviously. Each number is separated by a space.

1  3  2  4   5
1 -1  1 0  -1 5

The idea is to use these numbers to calculate some kind of a profit. The first line is price per item and the second line indicates an action. 1 means you bought it, -1 means you sold it, 0 means no action. So, to demonstrate things, you buy an item at $1, the running total is -1, you sell (add 3), subtract 2, ignore the no transaction, then add 5, leaving you with 5. Anyway, I have a script called test and if you run it, it allows you to enter a line of numbers separate by spaces, when you hit enter it displays the second line results. I think the idea is to feed lines in from testcase.txt to the check.sh file (the one I'm scripting now) and compare the program output with the expected output in testcase.txt. So, if I can get every odd line from testcase and feed it in, read the result output, then I can compare it. Is there a good way to do this? To call a .sh file within a .sh file?

set lines=`cat $PWD/testcase.txt`
set i=1

while ($i <= $#lines)
    echo $lines[$i]
    @ i = $i + 1
end

Oh yeah, if I can somehow feed a line from testcase to test.sh and store its result in a variable (ala the second line), then there might be a way to get it done.

To make things easier, I would convert to single lines first:

$ uname
Linux
$ cat testcase.txt
1  3  2  4   5
2 -1  1 0  -1 5
3  3  2  4   5
4 -1  1 0  -1 5
$ cat testcase.sh
sed "N; s/\n/ /" testcase.txt > testcase-2.txt
while read var1 var2 var3; do
  echo $var1
  # do whatever else you need
done < testcase-2.txt
$ ./testcase.sh
1
3

I am not sure I understand what you are after, but I suppose you could try doing something like this to compare the calculated result with what is in the last column of every second file:

#!/bin/bash
while read -a P && read -a S
do
  t=0
  for((i=0; i<${#P[@]}; i++)); do
    (( t -= P * S ))
  done
  printf "calculated: %d, file: %d\n" $t ${S}
done < file

awk:

awk '{split($0,P); getline; t=0; for(i=1; i<NF; i++) t-=P*$i; printf "calculated: %d, file: %d\n",t,$NF}'  file

Actually I think I have a better understanding of what I'm after now. I wrote out some psuedo code with what I'm trying to do but am unsure how to get each line from a file and send each line to the script.

set dir="$PWD/./test"
set dir2="$PWD/testcase.txt"
set ODD=""
set EVEN=""
set oddlines="sed -n 1~2p dir2 > ODD"
set evenlines=" awk 'NR%2==0' dir2 > EVEN"

set c=0

foreach line in oddlines
  result from test = test (line from odd)
  foreach line in evenlines
    if total from even matches total from test
       this means that this is successful test case
       output something with echo
    endif
  end
end

I apologize for before. What I wrote was kind of confusing and even I didn't fully understand what I was trying accomplish. Now I am sure what I want to do.

You can't just subtract numbers from the odd lines, it would need to be the sum product of the fields of the odd and even lines, no? That is what I used in the bits of code I suggested...

Yes, you are correct in what you say about the sum. Either doing that or seeing whether the return line provided from the function is the same as the one in the testcase file. I know diff works for files but maybe I can use it for smaller cases.:rolleyes:

---------- Post updated at 03:04 AM ---------- Previous update was at 02:06 AM ----------

Okay, I'm at the point where I am trying to pass an argument(odd line) to the ./test program and it keeps saying "command not found." I am trying to get the return value and store it in a variable. If I just run ./test in the terminal and hit enter, the cursor goes to the next line and I can enter something. When I call ./test in this way inside a script, it doesn't call it like this does it? ./test 0 0 0

Hopefully not. I know some of this code is repetitive and needs cleaned up but I am just trying to figure out how to get a value back from this program. Once I do this I can compare the line I got back to the even line in the evens file. Sorry, I am kind of new to shell programming so my code may look bad.

set dir="$PWD/./test"
set dir2="$PWD/testcase.txt"
set ODD=""
set EVEN=""
set oddlines=`sed -n 1~2p $PWD/testcase.txt > ODD`
set evenlines=`awk NR%2==0 $PWD/testcase.txt > EVEN`
set odd="`cat $PWD/ODD`"
set even="`cat $PWD/EVEN`"
set FILERETURN=""
set i=1
set j=1

while ($i <= $#odd)
 while ($j <= $#even)
  
  FILERETURN=$dir "$odd[$i]"
  echo FILERETURN
  #echo $odd[$i]
  
  #echo $even[$j]
  
   @ i = $i + 1
   @ j = $j + 1
  end
end

---------- Post updated at 12:55 PM ---------- Previous update was at 03:04 AM ----------

Well, I've almost done it. I managed to pipe pipe odd lines in, send them to the program and put them into a return variable. I've compared them in terminal and I am getting what I want. All the test cases run and I get a 10/10, my only problem is the trailing command not found messages. I do not know why this is happening. It's probably something really small but I don't have enough experience to immediately see it. Any helpful hints as to why I'm getting "command not found." Is there something wrong with my if statement?

set dir="$PWD/./test"
set dir2="$PWD/testcase.txt"
set ODD=""
set EVEN=""
set oddlines=`sed -n 1~2p $PWD/testcase.txt > ODD`
set evenlines=`awk NR%2==0 $PWD/testcase.txt > EVEN`
set fodd=$PWD/ODD
set odd="`cat $PWD/ODD`"
set even="`cat $PWD/EVEN`"
set FILERETURN=""
set i=1
set j=1
set counttot=0
set countpass=0

while ($i <= $#odd)
 while ($j <= $#even)
  
  set FILERETURN=(`echo $odd[$i] | $dir`)
     
    #echo $FILERETURN
    #echo $even[$j]
    if $FILERETURN == $even[$j] 
         @ countpass = $countpass + 1
    endif
  #echo $odd[$i]
  
  #echo $even[$j]
   @ counttot = $counttot + 1
   @ i = $i + 1
   @ j = $j + 1
  end
end

echo "passed/total tests" $countpass "/" $counttot
rm ODD EVEN

The output in terminal I get when I run check.sh is the following:

% check.sh
-1: Command not found.
0: Command not found.
-1: Command not found.
-1: Command not found.
-1: Command not found.
-1: Command not found.
-1: Command not found.
0: Command not found.
passed/total tests 10 / 10

You don't mention the shell that you are using (although we might infer it being bourneish). Should it be a modern one (bash, ksh), try running the script with the -x option. In bash, set sth will set positional parameters, not assign variables. If you want to assign variables, don't use spaces around the = sign. I don't know any command that is related/similar to your usage of the @ char.
And, using awk anyway, why don't you get the job done entirely in awk , as scrutinizer pointed out?

Unless you can explain the advantage to having two lines per record, simplify your life by putting all the data for one record on one line. Once all the data are on one line, the scripting and processing are much easier.