Up: Bash Builtins

16.1 readrec

The bash built-in read, when invoked with no options, consumes one line from standard input and makes it available in the predefined REPLY environment variable, or any other variable whose name is passed as an argument. This allows processing data structured in lines in a quite natural way. For example, the following program prints the third field of each line, with fields separated by commas, until standard input is exhausted:

     # Process one line at a time.
     while read
       echo "The third field is " `echo $REPLY | cut -d, -f 2`

However, read is not very useful when it comes to processing recutils records in the shell. Even though it is possible to customize the character used by read to split the input into records, we would need to ignore the empty records in the likely case of more than one empty line separating records. Also, we would need to use recsel to access to the record fields. Too complicated!

Thus, the readrec bash built-in is similar to read with the difference that it reads records instead of lines. It also “exports” the contents of the record to the user as the values of several environment variables:

Consider for example the following simple database containing contacts information:

     Name: Mr. Foo
     Email: foo@bar.com
     Email: bar@baz.net
     Checked: no
     Name: Mr. Bar
     Email: bar@foo.com
     Telephone: 999666000
     Checked: yes

We would like to write some shell code to send an email to all the contacts, but only if the contact has not been checked before, i.e. the Checked field contains no. The following code snippet would do the job nicely using readrec:

     recsel contacts.rec | while readrec
        if [ $Checked = "no" ]
           mail -s "You are being checked." ${Email[0]} < email.txt
           recset -e "Email = '$Email'" -f Checked -S yes contacts.rec
           sleep 1

Note the usage of the bash array when accessing the primary email address of each contact. Note also that we update each contact to figure as “checked”, using recset, so she won't get pestered again the next time the script is run.