Daemon Painter
Daemon Painter

Reputation: 3470

Bash: nested for loops on counters read from files, with decimal numbers

I'm beginning bash script exercises. I am trying to do a nested loop reading variables from two different sources like this:

for f in $(<f.txt)
do
    for l in $(<l.txt)
    do
        echo "$f $l"
    done
done

read -p "Press [enter] to continue..." 

Let f.txt and l.txt be files like the following:

25 
26 
26.8
26.9
27
27.1
27.2
27.3
27.4
27.5
28
29
30

and

0
0.5
1
1.5
2
2.5
3

I'm expecting two numbers separated by a white space, I'm getting a white space followed by what seems to be the second number. It only works as expected on the last iteration of the external loop.

As a beginner, is frustrating being unable to find out why this is happening. Can anybody please point me towards the correct direction?


EDIT: Unexpectedly, the DOS line ending was indeed the problem - and being a newbie I fall right into it.

I parsed my input files to get rid of the problem and got the expected output: two nested for loops printing two numbers separated by a space. I take the advantage of the edit to clarify:

expected output

25 0
25 0.5
25 1
25 1.5
25 2
25 2.5
25 3
26 0
26 0.5
26 1
26 1.5
26 2
26 2.5
26 3
26.8 0
etc...

I am willing to leave the thread open for people coming in - also to discuss what was said by chepner:

First, never use for loops like this; use while loops and the read command to read from a file.

Upvotes: 0

Views: 200

Answers (1)

chepner
chepner

Reputation: 531075

First, never use for loops like this; use while loops and the read command to read from a file.

while IFS= read -r f; do
  ...
done < f.txt

Knowing that, it's a "simple" step forward to call read twice at each step, with each one reading from separate file descriptors.

while IFS= read -r f; IFS= read -r l <&3; do
  echo "$f $l"
done < f.txt 3< l.txt

read always reads from standard input, so <&3 redirects file descriptor 3 to the standard input of this read command. 3< opens l.txt for reading on file descriptor 3.

Your code does not run the two iterations in parallel; it iterates over all of l.txt separately for each line in f.txt. (Mathematically, your nested loops compute a cross product of the values in f.txt and l.txt instead of a dot product.)

Upvotes: 2

Related Questions