16

So I'm trying to do something like the following:

while read line; do
    read userInput
    echo "$line $userInput"
done < file.txt

So say file.txt has:

Hello?
Goodbye!

Running the program would create:

Hello?
James
Hello? James
Goodbye!
Farewell
Goodbye! Farewell

The issue (naturally) becomes that the userinput read reads from stdin which in our case is file.txt. Is there a way to change where it's reading from temporarily to the terminal in order to grab user input?

Note: The file I am working with is 200,000 lines long. and each line is about 500 chars long. So keep that in mind if needed

indiv
  • 17,306
  • 6
  • 61
  • 82
Aram Papazian
  • 2,453
  • 6
  • 38
  • 45

1 Answers1

26

Instead of using redirection, you can open file.txt to a file descriptor (for example 3) and use read -u 3 to read from the file instead of from stdin:

exec 3<file.txt
while read -u 3 line; do
    echo $line
    read userInput
    echo "$line $userInput"
done

Alternatively, as suggested by Jaypal Singh, this can be written as:

while read line <&3; do
    echo $line
    read userInput
    echo "$line $userInput"
done 3<file.txt

The advantage of this version is that it's POSIX compliant (the -u option for read does not appear in POSIX shells such as /bin/sh).

l0b0
  • 55,365
  • 30
  • 138
  • 223
jcollado
  • 39,419
  • 8
  • 102
  • 133
  • 1
    @jcollado Though I have one small suggestion, instead of doing `exec` on a separate line you can have it written like this - `while read line <&3; do echo $line; read userInput; echo "$line $userInput"; done 3 – jaypal singh Jan 16 '12 at 23:12
  • Ok, I see, I cannot delete an accepted answer :/ – miku Jan 16 '12 at 23:17
  • @miku Since you permitted it I switched it over. – Aram Papazian Jan 17 '12 at 03:18
  • 1
    @JaypalSingh I've updated my answer. Thanks a lot for your suggestion because the code now works also in `sh`. – jcollado Jan 17 '12 at 09:11