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
do
  echo "The third field is " `echo $REPLY | cut -d, -f 2`
done

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
do
   if [ $Checked = "no" ]
   then
      mail -s "You are being checked." ${Email[0]} < email.txt
      recset -e "Email = '$Email'" -f Checked -S yes contacts.rec
      sleep 1
   fi
done

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.