Quoting line by line in a file in bash, without using stdin

The following situation deprives me.

I have a list.txt file that I want to run line by line, in a loop, in bash. A typical line in list.txt has spaces. The problem is that the loop contains a read command. I want to write this loop in bash, not something like perl. I can not do it: - (

This is how I usually write a loop to read from a file line by line:

while read p; do echo $p echo "Hit enter for the next one." read x done < list.txt 

This does not work, because of course, "read x" will be read from list.txt, not from the keyboard.

And this also does not work:

 for i in `cat list.txt`; do echo $i echo "Hit enter for the next one." read x done 

because the lines in list.txt have spaces.

I have two suggested solutions, both of which stink:

1) I could edit list.txt and globally replace all spaces with "THERE_SHOULD_BE_A_SPACE_HERE". Then I could use something like sed in my loop to replace THERE_SHOULD_BE_A_SPACE_HERE with a space, and I would set everything. I don't like this for the stupid reason that it will fail if any of the lines in list.txt contains the phrase THERE_SHOULD_BE_A_SPACE_HERE (so that malicious users can ruin me).

2) I could use a while loop with stdin, and then in every loop that I could run, for example. a new terminal that will not be affected by the move, including stdin in the original shell. I tried this, and I got it to work, but it was ugly: I want to wrap all this in a shell script, and I do not want the shell script to accidentally open new windows. What would be nice, and what might somehow be the answer to this question, would be if I could understand how to somehow invoke a new shell in the commands and submission commands to it without submitting a stdin to it, but I don’t can get it to work. For example, this does not work, and I really don't know why:

 while read p; do bash -c "echo $p; echo ""Press enter for the next one.""; read x;"; done < list.txt 

This attempt seems to fail because "reading x", although it is somehow in a different shell, still seems to be reading from list.txt. But I feel that I can be close to this - who knows.

Help!

+7
linux bash loops shell
source share
3 answers

You must open as a different file descriptor

 while read p <&3; do echo "$p" echo 'Hit enter for the next one' read x done 3< list.txt 

Update: Just ignore the lengthy discussion in the comments below. This has nothing to do with the question or this answer.

+15
source share

I would probably count the lines in the file and repeat each of them using, for example. SED. You can also read endlessly from stdin, while changing the condition: while true; and exit using ctrl + c.

 line=0 lines=$(sed -n '$=' in.file) while [ $line -lt $lines ] do let line++ sed -n "${line}p" in.file echo "Hit enter for the next ${line} of ${lines}." read -sx done 

AWK is a great tool for this. A simple way to iterate through the input would look like this:

 awk '{ print $0; printf "%s", "Hit enter for the next"; getline < "-" }' file 
+1
source share

Alternatively, you can read stderr, which is also connected to tty by default. The following is also a test for this assumption:

 ( tty -s <& 2|| exit 1 while read -r line; do echo "$line" echo 'Hit enter' read x <& 2 done < file ) 
0
source share

All Articles