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:
REPLY_REC
is set to the record read from standard input.
FIELD
named after each field found in
the record are set to the (decoded) value of the fields found in the
input record. When several fields with the same name are found in the
input record then a bash array is created.
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.