Search code examples
bashwhile-loopterminalshstdin

how to read multiple input files from stdin in bash script in nested while loop


i wanted to read two files from stdin in "while do nested loop" like file 1 first line and then process all file 2 input lines and then file 1 second line and process all lines from file 2 and so on.

example code

#!/bin/bash
cd ~/files/ ;
while read line1;
do 
 echo "$line1"output;
while read line2;
do
echo $line1;
echo $line2;
echo "$line1"test"line2" | tee -a output.txt ;

done < "${1:-/dev/stdin}" ;

i am reading file input from stdin using ./script.sh file1.txt but i wanted to input two files like

./script.sh file1.txt file2.txt
i tried 
done < "${1:-/dev/stdin}" ;
done < "${2:-/dev/stdin}" ; 
its not working .
 also tried file descripters
like 
while read line1<&7;
while read line2<&8;
input like ./script.sh file1.txt 7< file2.txt 8
and it throws bad file descriptor error .

Solution

  • To get access to both files within the inner loop, open them on different file descriptors. Here's an example using FD #3 and #4:

    #!/bin/bash
    
    while read line1 <&3; do    # Read from FD #3 ($1)
        while read line2 <&4; do    # Read from FD #4 ($2)
            echo "line1: $line1, line2: $line2"
        done 4<"${2:-/dev/stdin}"    # Read from $2 on FD #4
    done 3<"${1:-/dev/stdin}"    # Read from $1 on FD #3
    

    Here's an example run:

    $ cat file1.txt 
    one
    two
    $ cat file2.txt 
    AAA
    BBB
    $ ./script.sh file1.txt file2.txt 
    line1: one, line2: AAA
    line1: one, line2: BBB
    line1: two, line2: AAA
    line1: two, line2: BBB
    

    BTW, a few other recommendations: You should (almost) always put variable references in double-quotes (e.g. echo "$line1" instead of echo $line1) to avoid weird parsing. You don't need semicolons at the end of lines (I used them in the while ... ; do statements above, but only because I put the do on the same line). And you should (almost) always check for error when using cd in a script (so it doesn't just keep running in the wrong place, with unpredictable results).

    shellcheck.net is good at pointing out common scripting mistakes; I recommend it!