ABM
ABM

Reputation: 23

Bash scripting, read two files line by line

I would like to print the first value (in file2) greater than a value of file1. To achieve that, I have the following code:

file1="valueA.txt"
file2="valueB.txt"
     
while IFS= read -r line
  do
  printf '%s \n' "$line" 
  while IFS= read line1 && (( $(echo "$line > $line1" |bc -l ) ));
     do 
     printf '%s \n' "$line1" 
     done <"$file2"
                    
     done <"$file1"

Here is an example for valueA.txt:

6.40693
14.2077
14.2829
50.7346

Here is an example for valueB.txt:

5.89669
28.4962
35.7508
36.2576
43.2666
93.3357
102.845
106.821
115.623

My code is expected to do this:

and so on.

However, I'm not getting any result inside the second While loop.

Upvotes: 1

Views: 303

Answers (3)

thanasisp
thanasisp

Reputation: 5965

with awk

Input files are always sorted. You can modify the print statements as you wish, I print more to demonstrate how it works (and you have not added yet the exact sample output). Variable resume is used to ensure time complexity remains linear to file length. Usage: awk -f tst.awk file2 file1.

> cat tst.awk
BEGIN { resume=1 }
NR==FNR { a[NR]=$0; next }
{ 
    for (i=resume;i in a;i++) {
        print("i=" i)
        if (a[i]>$0) { print "First number found >=", $0, "is",a[i]
            resume=i
            break
        }
    }
}

Testing:

> cat file1
6.40693 
14.2077 
14.2829 
50.7346 
100000

I have added a final number greater than all numbers, it prints nothing for it.

> cat file2
5.89669
28.4962
35.7508
36.2576
43.2666
93.3357
102.845
106.821
115.623

.

> awk -f tst.awk file2 file1
i=1
i=2
First number found >= 6.40693  : 28.4962
i=2
First number found >= 14.2077  : 28.4962
i=2
First number found >= 14.2829  : 28.4962
i=2
i=3
i=4
i=5
i=6
First number found >= 50.7346  : 93.3357
i=6
i=7
i=8
i=9

Upvotes: 0

chepner
chepner

Reputation: 530970

Use awk to get the minimum value of file 1, then use awk again to get the first value greater than that minimum.

min_file1=$(awk 'NR == 1 { smallest=$1 }; NR > 2 && $1 < smallest { smallest=$1 }; END {print smallest}' file1)
awk -v x=$min_file1 '$1 > x {print $1; exit}' file2

Upvotes: 0

glenn jackman
glenn jackman

Reputation: 246764

I suspect this is what you want: read lines from the 2 files simultaneously:

while read -r a <&3 && read -r b <&4; do
    if [[ $(bc -l <<< "$a > $b") == 0 ]]; then
        printf "%f\n" "$b"
        break
    fi
done 3<valueA.txt 4<valueB.txt

Upvotes: 1

Related Questions