Friday, 6 March 2015

Scripting: Reading a file line by line using while loop

While writing shell scripts, we may come across a situation to read a file line by line.

I will explain this with the help of an example.

Assume that, I have a file /home/manoj/bash/manoj.txt. The content of the file is below:
---
[root@MANINMANOJ bash]# cat manoj.txt
This is a sample file
This file belongs to Manoj
Manoj, can read and write in this file
---

I want to read the content line by line and number the lines.

The script looks as below:
----
#!/bin/bash

i=1

echo ########

while read line; do
{
echo "$i: $line"
((i++))
}
done < /home/manoj/bash/manoj.txt
echo ########

echo "Total number of line in file $i"
------

The output after executing the script looks as below:
-----
[root@MANINMANOJ]# sh reading.sh

1: This is a sample file
2: This file belongs to Manoj
3: Manoj, can read and write in this file

Total number of line in file 4
------

Now, let see if you are using "cat" command to pass the content of the file to while loop:
-----
#!/bin/bash

i=1

echo ########

cat /home/manoj/bash/manoj.txt |while read line; do
{
echo "$i: $line"
((i++))
}
done
echo ########

echo "Total number of line in file $i"
-----

Output looks as below:
-----
[root@MANINMANOJ]# sh reading.sh

1: This is a sample file
2: This file belongs to Manoj
3: Manoj, can read and write in this file

Total number of line in file 1
-------

By comparing both the output we can see that there is a difference in as highlighted. 

This is because while loop along with pipe (|) (cat $FILE | while read line; do ... ) and also incremented the value of (i) inside the loop and at the end, output is wrong value of i. The main reason for this is that, the usage of pipe (|) will create a new sub-shell to read the file and any operation within this while loop (example - i++) will get lost when this sub-shell finishes the operation.

:)

No comments:

Post a comment

Note: only a member of this blog may post a comment.