2

I need to read from multiple file in one loop. I have one file with X coords, one file with Y coords and one file with chars on those coords.

For now I use paste to put these files together, and then in a while loop use cut to separate them like this:

paste x-file y-file char-file | while -r line; do
    Y=$(echo "$line" | cut -d\  -f1)
    X=$(echo "$line" | cut -d\  -f2)
    CHAR=$(echo "$line" | cut -d\  -f3)
done

but the problem with this is that it's really slow (calling cut again and again).

How should I do this to have in each loop proper values in $Y, $X and $CHAR while speeding things up?

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
graywolf
  • 7,092
  • 7
  • 53
  • 77
  • 1
    Something like `while read X Y CHAR`? – Lev Levitsky May 20 '13 at 07:36
  • you are right man ^_^ thanks. If you want reputation for accepted answer, just copy your comment (don't see option to accept comment as answer..). – graywolf May 20 '13 at 07:44
  • See [Looping through the content of a file in Bash](https://stackoverflow.com/a/41646525/6862601). – codeforester Jul 31 '18 at 16:12
  • Possible duplicate of [Looping through the content of a file in Bash](https://stackoverflow.com/questions/1521462/looping-through-the-content-of-a-file-in-bash) – codeforester Jul 31 '18 at 16:12
  • @codeforester, I don't see that as an adequate duplicate -- this question covers iterating over multiple files in lockstop. The OP isn't very clear about that, because they're *assuming* `paste` as a preprocessing step, but just clarifying that (making the `paste` explicit) would help; I'm editing that in now. – Charles Duffy Jul 31 '18 at 17:40
  • I agree it is not a true duplicate, though closely related. My answer to the other question does cover "Reading from more than one file at a time". – codeforester Jul 31 '18 at 17:42
  • Fair enough -- but there's much less digging to get to that answer here than there, so it's clearer to a reader *why* it's a good duplicate (and hence, likely to get less pushback). – Charles Duffy Jul 31 '18 at 17:48

2 Answers2

7

You can call read thrice, each from a different file descriptor.

# Use && to stop reading once the shortest file is consumed
while read -u 3 -r X &&
      read -u 4 -r Y &&
      read -u 5 -r CHAR; do
    ...
done 3< X.txt 4< Y.txt 5< CHAR.txt 

(-u is a bash extension, used for clarity. For POSIX compatibility, each call would look something like read -r X <&3.)

chepner
  • 497,756
  • 71
  • 530
  • 681
4

I'm not sure how to do it without paste, but you can avoid cut assigning all variables in one read:

while read -r X Y CHAR; do
    echo "X = $X; Y = $Y; CHAR = $CHAR";
done < "$file"
Lev Levitsky
  • 63,701
  • 20
  • 147
  • 175