3

So here's my script :

count=0
cat myfile | while read line
do
    #some stuff...
    let count++
    echo $count
done
echo $count

The last echo statement output 0 instead of the number of lines in the file, although the echo statement in the while loop prints the incrementing value.

The problem is with the piping, because, with a simple while loop, the last echo statement prints the correct value. How can I get this to work?

P Shved
  • 96,026
  • 17
  • 121
  • 165
subb
  • 1,578
  • 1
  • 15
  • 27

2 Answers2

4

In Bash, you can use process substitution and avoid the temporary file and the variables in the while loop will be retained.

count=0
while read -r line  # you should almost always use -r
do
    #some stuff...
    (( count++ ))   # alternative form 
    echo $count
done < <(tac myfile)
echo $count
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
2

When using pipes, a new subshell is created and any variables in it are lost after it. Use the following code instead:

count=0
while read line
do
    #some stuff...
    let count++
    echo $count
done < myfile
echo $count

Example with a command: tac:

count=0
# Create a random file
tmpfile=$(mktemp)
tac myfile > $tmpfile
while read line
do
    #some stuff...
    let count++
    echo $count
done < $tmpfile
# remove temp file
rm $tmpfile
echo $count
Lekensteyn
  • 64,486
  • 22
  • 159
  • 192
  • Thanks, but I would also like to read the file in reverse, using tac. Can I do that using ...done < myfile? – subb Nov 21 '10 at 09:00
  • No, unfortunately not. As a workaround, you can output the contents of the file in a temporary file, and read the contents from that. I'll update my answer with an example. – Lekensteyn Nov 21 '10 at 09:06