From bc5e73430b5b57351869854f46a3bfc68a1f3185 Mon Sep 17 00:00:00 2001 From: John Darrington Date: Fri, 10 Aug 2012 21:15:37 +0200 Subject: [PATCH] User manual: Added the start of a new tutorial section. --- ChangeLog | 4 + doc/recutils.texi | 373 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 377 insertions(+), 0 deletions(-) diff --git a/ChangeLog b/ChangeLog index 14e98f1..5bbc2e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2012-08-10 John Darrington + + * doc/recutils.texi Added start of new tutorial section covering recutils use. + 2012-08-05 Jose E. Marchesi src,doc: support for dot notation in simple fexes. diff --git a/doc/recutils.texi b/doc/recutils.texi index 56b4e08..b94a926 100644 --- a/doc/recutils.texi +++ b/doc/recutils.texi @@ -90,6 +90,7 @@ Advanced Topics and Reference * Regular Expressions:: Flavor of regexps supported in recfiles. The Recutils +* Using the Recutils:: How to use recutils to maintain and query recfiles. * Common Options:: Common command line arguments for the record utilities. * recinf:: Printing information about rec files. @@ -1707,6 +1708,378 @@ The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to sub-expressions within groups. address@hidden Using the Recutils address@hidden Using the Recutils + +The previous chapters describe how to create and edit recfiles by hand. +Now we will introduce utilities to extract data from your already +created recfiles, and to automate the process using the recutils. + address@hidden +* Checking recfiles for errors:: +* Retrieving data:: +* Joining records using foreign keys:: address@hidden menu + address@hidden Checking recfiles for errors address@hidden Checking recfiles for errors +Sometimes, when creating a recfile by hand, typographical errors will +occur. It can be hard to spot such errors visually. Fortunately +there is a tool called @command{recfix} which can find these errors. + +One easy mistake is to forget the colon separating the field name from +its value. + address@hidden +%rec: Article +%key Id + +Name: Thing +Id: 0 address@hidden example + +Running @command{recfix} on this file will immediately tell us that +there is a problem: + address@hidden +$recfix --check inventory.rec +inventory.rec: 2: error: expected a record address@hidden example + +Here, @command{recfix} has diagnosed a problem on line 2. +If, as in this case, @command{recfix} shows there is a problem with +the recfile, you should attend to that problem before trying to use +any other recutils program on that file, otherwise strange things +could happen. + +It is a good idea therefore to get into the habit of running @command{recfix} on +a file after editing it, and before trying other commands. +In fact, the @code{--check} flag is not necessary, because that is the +default operation. + + + address@hidden Retrieving data address@hidden Retrieving data + +Since recfiles are always human readable, you could lookup data simply by +opening an editor and searching for the desired information. +Or you could use a standard tool such as @command{grep} to extract +strings matching a pattern. +However, recutils provide a more powerfull and flexible way to lookup +data. + +Consider the following example recfile, which we shall assume is +saved in a recfile called @file{acquaintances.rec}: + address@hidden +Name: Ada Lovelace +Age: 36 + +Name: Peter the Great +Age: 53 + +Name: Bart Simpson +Age: 10 + +Name: Adrian Mole +Age: 13.75 address@hidden example + address@hidden It contains a names of people along with their respective ages. +Suppose we want to get a list of the names of all the children. +It would not be easy to do this using @command{grep}. +Neither would it, for any reasonably large recfile, be feasible to search +manually for the children. +Fortunately the @command{recsel} command provides an easy way to do +such a lookup: address@hidden +$ recfix acquaintances.rec +$ recsel -e "Age < 18" -P Name acquaintances.rec +Bart Simpson +Adrian Mole address@hidden example + address@hidden Before @command{recsel} command there is a call to address@hidden, just in case @file{acquaintances.rec} contains +something problematic. +Let us look at each of the arguments to @command{recsel} in turn: +Firstly we have @code{-e} which tells @command{recsel} to lookup records +matching the expression @code{Age < 18} --- in other words all those persons +whose ages are less than 18. +Next there is @code{-P} which tells recsel to print out the value of +the @code{Name} field --- because we want just the name, not the entire record. +The final argument is the name of the file from whence the records are +to come: @file{acquaintances.rec}. + +Rather than explicitly storing ages in the recfile, a more realistic example +might have the date of birth instead. This would alleviate the need +to update people's ages each year: + address@hidden +# Date of Birth +%type: Dob date + +Name: Alfred Nebel +Dob: 20 April 2010 +Email: alf@@example.com + +Name: Bertram Worcester +Dob: 3 January 1966 +Email: bert@@example.com + +Name: Charles Spencer +Dob: 4 July 1997 +Email: charlie@@example.com + +Name: Dirk Hogart +Dob: 29 June 1945 +Email: dirk@@example.com + +Name: Ernest Wright +Dob: 26 April 1978 +Email: ernie@@example.com address@hidden example + address@hidden Now we can achieve a similar result as before, by looking up +the names of all those persons who were born after a particular date: address@hidden +$ recfix acquaintances.rec +$ recsel -e "Dob >> '31 July 1994'" -p Name acquaintances.rec +Name: Alfred Nebel +Name: Charles Spencer address@hidden example + address@hidden The @code{>>} operator means ``later than'', and is used +here to select a date of birth after 31st July 1994. +Note also that this example uses a lower case @code{-p} whereas the preceeding example +used the upper case @code{-P}. The difference is, that @code{-p} prints the field label +and field value, whereas @code{-P} prints just the value. address@hidden accepts more than one @code{-e} argument, +in which case records which satisfy all expressions are selected. +You can provide more than one field label to @code{-P} or @code{-p} in order to select +additional fields to be displayed. +For example, if you wanted to send an email to all children 14 years of age or older, +and today's date were 1st~August 1994, then you could use the following command to get +the name and email address of all such children: + address@hidden +$ recfix acquaintances.rec +$ recsel -e "Dob >> '31 July 1994' && 'Dob << 01 August 1998'" -p Name,Email acquaintances.rec +Name: Charles Spencer +Email: charlie@@example.com address@hidden example + address@hidden As you can see, there is only one such child in the record set. + address@hidden Joining records using foreign keys address@hidden Joining records using foreign keys + +Suppose you wanted to add the residential address of the people in +the @file{acquaintances.rec} file. + +One way to do this is as follows: address@hidden +%type: Dob date + +Name: Alfred Nebel +Dob: 20 April 2010 +Email: alf@@example.com +Address: 42 Abbeter Way, Inprooving, WORCS +Telephone: 01234 5676789 + +Name: Mandy Nebel +Dob: 21 February 1972 +Email: mandy@@example.com +Address: 42 Abbeter Way, Inprooving, WORCS +Telephone: 01234 5676789 + +Name: Bertram Nebel +Dob: 3 January 1966 +Email: bert@@example.com +Address: 42 Abbeter Way, Inprooving, WORCS +Telephone: 01234 5676789 + +Name: Charles Spencer +Dob: 4 July 1997 +Email: charlie@@example.com +Address: 4 Datwos Close, Little Worning, BERKS +Telephone: 09876 5432109 + + Name: Dirk Spencer +Dob: 29 June 1945 +Email: dirk@@example.com +Address: 4 Datwos Close, Little Worning, BERKS +Telephone: 09876 5432109 + +Name: Ernest Wright +Dob: 26 April 1978 +Email: ernie@@example.com +Address: 1 Downthe Road, Elsewhere Port, LANCS address@hidden example + + +This will work fine. +However you will notice that there are two addresses where more than one person +live (presumably they are members of the same family). +This has a number of disadvantages: address@hidden @minus address@hidden You have to type (or copy) the same information several times. address@hidden Should a family move house, then you would have to update the addresses (and telephone number) of all the family members. address@hidden A typing error in one of the addresses would lead an automatic query to erroneously suggest that the persons lived at different addresses. address@hidden It unnecessarily increases the size of the recfile. address@hidden itemize + +A better way would be to separate the addresses and persons into different record sets. +The first record set might look like this: + address@hidden +%rec: Person +%type: Dob date +%type: Abode rec Residence + + +Name: Alfred Nebel +Dob: 20 April 2010 +Email: alf@@example.com +Abode: 42AbbeterWay + +Name: Mandy Nebel +Dob: 21 February 1972 +Email: mandy@@example.com +Mobile: 0555 342123 +Abode: 42AbbeterWay + +Name: Bertram Nebel +Dob: 3 January 1966 +Email: bert@@example.com +Abode: 42AbbeterWay + +Name: Charles Spencer +Dob: 4 July 1997 +Email: charlie@@example.com +Abode: 4DatwosClose + +Name: Dirk Spencer +Dob: 29 June 1945 +Email: dirk@@example.com +Mobile: 0555 342123 +Abode: 4DatwosClose + +Name: Ernest Wright +Dob: 26 April 1978 +Abode: ChezGrampa + address@hidden example + address@hidden and the second (which follows in the same file), like this: + address@hidden + +%rec: Residence +%key: Id + +Address: 42 Abbeter Way, Inprooving, WORCS +Telephone: 01234 5676789 +Id: 42AbbeterWay + +Address: 4 Datwos Close, Little Worning, BERKS +Telephone: 09876 5432109 +Id: 4DatwosClose + +Address: 1 Downthe Road, Elsewhere Port, LANCS +Id: ChezGrampa address@hidden example + +Here you can see that there are two record sets @i{viz:} @code{Person} +and @code{Residence}. +There are six persons, but only three residences, because some residences +accommodate more than one person. +Note also that the @code{Residence} descriptor has the entry @code{%key: Id} +whilst the @code{Person} descriptor has @code{%type: Abode rec Residence}. +This is because @code{Abode} is the foreign key which identifies the residence +where a person lives. + +We could have declared the @code{Id} field as @code{%auto}. This would have had +the advantage that we need not manually update it. +However, we decided that the @code{Abode} field values in the @code{Person} records +are better as alphanumeric fields, so that they can contain +human readable values. In this way, it is self-evident by reading a @code{Person} +record where that person lives. +Yet since the @code{Id} field is declared using the @code{%key} special field +name, you can be sure that you don't accidently reuse an existant key. + +The above example has also added a new field to the @code{Person} record set +to contain that person's mobile phone number. Note that the @code{Telephone} +field belongs to the @code{Residence} record set because that contains the telephone +number of the home, +whereas @code{Mobile} belongs to @code{Person} since mobile telephones are normally +used exclusively by one individual. + +If we want to look up the name and address of persons in our recfile, we can +use the @command{recsel} as before. +Because we now have more than one record set in the @file{acquaintances.rec} +file, we have to tell @command{recsel} from which record set we want to lookup +records. +We do this with the @code{-t} flag as follows: + address@hidden +$ recsel -t Person -P Name,Abode acquaintances.rec +Alfred Nebel +42AbbeterWay + +Mandy Nebel +42AbbeterWay + +Bertram Nebel +42AbbeterWay + +Charles Spencer +4DatwosClose + +Dirk Spencer +4DatwosClose + +Ernest Wright +ChezGrampa address@hidden example + +This result tells us the names of all the people in the recfile, as well as +giving a concise and hopefully effective reminder telling us where they live. +However these results would not be useful to someone unacquainted with the +individuals. +They need a list of names and full addresses. +We can use @command{recsel} to produce such a list: + address@hidden +$ recfix acquaintances.rec +$ recsel -t Person -j Abode acquaintances.rec +Name: Charles Spencer +Dob: 4 July 1997 +Email: charlie@@example.com +Abode_Address: 4 Datwos Close, Little Worning, BERKS +Abode_Telephone: 09876 5432109 +Abode_Id: 4DatwosClose + +Name: Dirk Spencer +Dob: 29 June 1945 +Email: dirk@@example.com +Mobile: 0555 342123 +Abode_Address: 4 Datwos Close, Little Worning, BERKS +Abode_Telephone: 09876 5432109 +Abode_Id: 4DatwosClose + +Name: Ernest Wright +Dob: 26 April 1978 +Abode_Address: 1 Downthe Road, Elsewhere Port, LANCS +Abode_Id: ChezGrampa address@hidden example + +The @code{-t} flag we have seen before. It tells @command{recsel} that we want +to extract records of type @code{Person}. +The @code{-j} flag is new. It says that we want to perform a @dfn{join}. +Specifically we want to join the @code{Person} records according to their @code{Abode} field. + @node Common Options @chapter Common Options -- 1.7.2.5