Linux Topic
   >  Shell Scripts
   >  Using Comments
   >  Passing Arguments to Scripts
   >  Using Conditional Statements
   >  Using Loop Statements
   >  Reading and Writing Files
   >  Script Permissions
   >  Cron and Scheduling
   >  A Scripting Example
   >  Other Scripting Languages

 

Reading and Writing Text Files

Reading from Text Files

The simplest way of reading through a file, is to basically read it a chunk (-normally a line) at a time using a while/until loop as given below:

while read <variable name>
do <process the current line>
done <input filename>

The read command will read the next line from the $STDIN and place it in the <variable name>; it will return a true (non-zero) value if a line could be read or a false (zero) value if not - making it an ideal condition to the used by the while loop. For each line read, the <process the current line> block will be executed.

The code following the done uses I/O Redirection to alter the $STDIN (temporary - for the life of the while loop) to the file given in <input filename>.

Let's look at a simple example:

echo "*** The Start ****"
while read fileLine
do
   echo "Current value of fileLine is $fileLine"
done < inputFile

echo "*** The End ****"

This code simply reads the file "inputFile", one line at a line, printing it out each line as it goes. Just to prove the output is coming from the loop, I've bookended it with some start/end text. Now, let's suppose the file "inputFile" contains the following:

this is the first line
this is the second line
this is the last line

If you run the above code with the input given, you'll get the following output:

$ ./myScript.sh
*** The Start ****
Current value of fileLine is this is the first line
Current value of fileLine is this is the second line
Current value of fileLine is this is the last line
*** The End ****

Writing Data to a Text File

To write to a file, we again use I/O Redirection: this time, it's used to alter the $STDOUT of the echo statement to point to the <output filename>. Here is the example from the previous section, altered to append the contents of the "inputFile" to a new file called "outputFile":

echo "*** The Start ****"
while read fileLine
do
   echo "Current value of fileLine is $fileLine" >> outputFile
done < inputFile

mv inputFile inputFile.old
mv outputFile inputFile

echo "*** The End ****"

If we run the above (-and assuming "outputFile" is initially empty), the output should look as follows:

$ ./myScript.sh
*** The Start ****
*** The End ****
$ more outputFile
Current value of fileLine is this is the first line
Current value of fileLine is this is the second line
Current value of fileLine is this is the last line

Updating an Existing File

There is no easy way of updating an existing file with BASH scripting, so most programmers simply create a new file then rename it to the original filename (-normally, we save the old version as well, in case of errors). Here's a simple example of updating a file:

echo "*** The Start ****"
while read fileLine
do
   echo "Current value of fileLine is $fileLine" >> outputFile
done < inputFile

mv inputFile inputFile.old
mv outputFile inputFile

echo "*** The End ****"

The only differences to the version in the section above, are those two mv commands near the end: the first backs up the existing file and the second renames the new file to the same name as the original. In practise,of course, we'd want to put at least some basic error handling around these, to ensure the files exist before we start renaming them: see the section below for details.


Testing an Existing File

Linux provides many File Test Operators that allow you to test various properties of a file. There are many of these - and we're just going to cover the basics here - but you use them all in the same way (-normally as part of an if statement) as a good list can be found at tldp.org/LDP/abs/html/fto.html or by typing "BASH File Test Operators" into a search engine). Here's a flavour of the sort of things that are available:

File Test OperatorDescription
-eTrue if the file exists, false if not
-sTrue if the file is not empty, false if it is
-dTrue if the file is a directory, false if not
-rTrue if the script has permission to read the file, false if not
-wTrue if the script has permission to write the file, false if not
-xTrue if the script has permission to execute the file, false if not

Let's update the script from the previous section to include some basic error handling. Take a look at the following:

echo "*** The Start ****"
if [ -f "outputFile" ]; then
   # remove any old outputFile hanging around
   rm outputFile
fi

while read fileLine
do
   echo "Current value of fileLine is $fileLine" >> outputFile
done < inputFile

if [ -s "outputFile" ]; then
   # overwrite the old version of the input file only if new file is non blank
   mv inputFile inputFile.old
   mv outputFile inputFile
fi

echo "*** The End ****"

As you can see, we have added two if statements:

  • The first executes the command rm outputFile only if that file exists
  • The second executes the two mv commands only if the "outputFile" is not blank

We recommend you always add such checking as it will save you a lot of time debugging and will, hopefully, save you from overwriting or losing valuable data with junk.


HomeSite IndexDesktop GuideServer GuideHints and TipsHardware CornerVideo SectionContact Us

 sitelock verified Firefox Download Button