I have a text file full of several hundred lines of sequences like this:

    b 29.
    b 52.
    c 84.
    c 83.
    c 94.
    c 93.
    c 61.
    b 38.
    c 81.
    c 92.
    c 28.
    c 37.
    c 27.

    lara@batcuter:~/.asd/a-new-way-of-studying-go$ wc -l game7
    271 game7

and the following script, which separates a text file into two files, one of which consists of odd-numbered lines and one of which consists of even-numbered lines, then reads both files into a while IFS loop, printing a line from each at a time:

#testing liquor-where-twin-twas-born

awk '{print>"line-"NR%2}' $@

while IFS= read -r lineA && IFS= read -r lineB <&3; do
  echo "$lineA";
  echo "$lineB" 
done <line-1 3<line-0

which unfortunately gives something not quite the same as the input file, due to the fact that one file was one line longer than the other.

    lara@batcuter:~/.asd/a-new-way-of-studying-go$ testing-liquor game7 > test
    lara@batcuter:~/.asd/a-new-way-of-studying-go$ diff test game7
    > b 7.

Obviously, since the file is 271 lines long, splitting it in half yields two files, one of which is 136 lines, and one of which is 135 lines. I need to fix the IFS while loop to return zero differences. At first, I thought using read ... || read ... would help. But actually, that just bloated the output, inserting more than a single a newline between each entry, and shaving off the last line (the line that ended up in the file with the odd number of lines), as did all the other solutions I tried.


Tell the person who suggested || that he's an idiot. Using || makes the snippet read all the lines from fileA first, then all the lines from fileB, because as long as read lineA returns true, read lineB is not executed. Instead, call read both times, saving the return status, then test the return statuses.

    IFS= read -r lineA; statusA=$?
    IFS= read -r lineB; statusB=$?
    [ $statusA -eq 0 ] || [ $statusB -eq 0 ]
do …

You can go on to test $statusA and $statusB inside the loop if you need to know whether a file has run out (the line contents will be empty, but this is not distinguishable from an empty line).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.