home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / games / patterns.zip / CHP.DOC next >
Text File  |  1988-04-03  |  28KB  |  630 lines

  1.  
  2.                              CHP.EXE
  3.           Changes Those Substrings from a Set of Files
  4.      That Are Matched by a Given Regular Expression Pattern
  5.  
  6.                                by
  7.                        Robert A. Magnuson
  8.                          DMB, DCRT, NIH
  9.                        Bethesda, MD 20892
  10.                             Mar 1988
  11.                         Revised Apr 1988
  12.  
  13.  
  14.  
  15. CHP (for Change via Pattern) is a tool used to search DOS files
  16. for those lines that contain a match for a specified pattern.
  17. Matches are changed according to the replacement specification.
  18. All input lines--changed or not--are written to stdout.
  19.  
  20.     [This document is intended to be read from the screen.
  21.     It contains some characters which will probably not print
  22.     correctly on a printer.]
  23.  
  24. A DOS command line that invokes CHP contains a number of
  25. arguments.  The syntax is summarized by the following:
  26.  
  27.            ┌────────────────┐            ┌─────┐
  28.            │ options:        │  ┌─ <pat> ─┴ <r> ─┤  ┌─────────────┐
  29.       CHP ─┴─ / ─┬ <ltr> ┬──┴──┤                ├──┴─┬ <file> ┬──┴─
  30.                  └──────┘      └─── <patfile> ──┘    └───────┘
  31.  Option Definitions:
  32.  ───────────────────                   │            <r> replaces the match,
  33.  /c  <r> is capitialized like the match│            is required unless /d.
  34.  /d  delete match (there is no <r>)    │
  35.  /e  no more option args even if       │In <r>:
  36.      next arg begins with /            │\0 is  the entire match,
  37.  /f  pattern, replacement in <patfile> │\δ is  the δth group where δ is 1-9,
  38.  /v  verify change                     │\u upcases next \δ where δ is 0-9,
  39.  /x  compare case exact                │\l lowercases next \δ,
  40.  ──────────────────────────────────────┤\i initialcaps next \δ,
  41.  Pattern, replacement can contain hexa-│\α is  α, where α is any other byte,
  42.  decimal byte representations "\xhh".  │anything else is itself.
  43.  
  44.  
  45. First there may be optional arguments specifying various CHP
  46. options.  Then there is the required pattern which is used to
  47. match the lines taken from the files.  Next, there is the usually
  48. required replacement specification.  Then come the filenames
  49. which can be wildcarded.  If no filenames appear, CHP gets its
  50. input from stdin.
  51.  
  52.     The arguments can optionally be enclosed in double
  53.     quotes.  The enclosing quotes are stripped off and not
  54.     seen by CHP.  Should you need to have a double quote
  55.     within an argument, the argument must be double quoted
  56.     and the internal double quote must be escaped by
  57.     preceding it with a backslash.  This treatment of the
  58.     double quotes is done by the argc/argv mechanism of the C
  59.     compiler.  This mechanism does not allow for null
  60.     arguments.  What looks like a quoted nullstring--two
  61.     consecutive doublequotes--is treated like whitespace
  62.     between arguments.  [CHP is implemented in Borland
  63.     TurboC.]
  64.  
  65.  
  66. CHP exits with ERRORLEVEL set to one if some matched substrings
  67. were changed, to zero if no changes occurred, and to two for
  68. syntax problems.
  69.  
  70. OPTION ARGUMENTS:
  71.  
  72. CHP options are specified by the presence or absence of various
  73. option letters in option arguments.  Any option argument must
  74. begin with a slash and must appear in front of the other kinds of
  75. arguments.  Any number of legal option letters can appear in an
  76. option argument.  Thus, you can have multiple option arguments,
  77. perhaps each with a single option letter (and each beginning with
  78. a slash), or just one option argument containing all of the
  79. option letters desired.  CURRENTLY, ALL LEGAL CHP OPTION LETTERS
  80. ARE lower case.
  81.  
  82.     For the sake of readability, the above syntax diagram
  83.     shows only the case where all option letters appear in
  84.     one option argument.
  85.  
  86. A CHP syntax error occurs when illegal option letters appear, and
  87. when required arguments are missing.  The <p> argument is
  88. required.  The <r> argument is required unless the /d option is
  89. present.
  90.  
  91. When a syntax error occurs CHP prints a boxed syntax diagram
  92. containing terse instructions on how to use CHP.  This mechanism
  93. can be deliberately tripped in order to get on-screen help.  The
  94. suggested way is to invoke CHP with no arguments--thus causing
  95. the no-<p> syntax error.
  96.  
  97. The /d option asks that the matches be deleted, which means
  98. replacing the matches with nullstrings.  If the compiler used in
  99. writing CHP permitted null command-line arguments, deletion would
  100. be done by making the replacement null.  When the /d option is
  101. taken, the first argument beyond the pattern (i.e., the one that
  102. would be <r>)--if any--is taken to be the first filename.
  103.  
  104. The /v option permits interractive verification as to whether
  105. each or any of the found matches should be changed.  In that
  106. case, CHP writes the line number and the line's contents on the
  107. screen with the current match highlighted.  Then, prompted by CHP
  108. whether to make this change, the user has six options:  change
  109. it, don't change it, change it and all following matches, change
  110. neither this one nor any following matches, quit the program
  111. immediately without finishing, or get help on what choices there
  112. are.
  113.  
  114. In matching the pattern, case (upper or lower) is ignored unless
  115. the /x option is taken.
  116.  
  117. The /e option permits the pattern to start with a
  118. slash--otherwise the pattern would look like another option
  119. argument.
  120.  
  121. The /c option capitalizes <r> like the match.  More fully, /c
  122. makes <r>'s first constant letter the same case as the match's
  123. first letter.  A constant byte in <r> is one appearing directly,
  124. i.e., not part of the yield of \0 or \1, etc.  If the match has
  125. no letters, no case change is made in <r>.
  126.  
  127. Usually the pattern and replacement appear directly in the DOS
  128. command line.  However, the DOS command line maximum length is
  129. severely restricted.  Should there not be enough room for the
  130. pattern and replacement, they can be placed in a file (as the
  131. first and second lines).  The /f option is then used to signify
  132. that the <p> parameter is not the pattern, but rather the name of
  133. a file containing both the pattern and replacement.
  134.  
  135.     The doublequoting convention that is carried out by the
  136.     argc-argv treatment of the command line arguments does
  137.     not apply to the pattern or replacement contained in a
  138.     file (when the /f option is in effect).  Doublequotes,
  139.     spaces, etc., are taken literally.
  140.  
  141.  
  142. REGULAR-EXPRESSION PATTERN-MATCHING:
  143.  
  144. CHP selects the substrings in the lines by means of pattern
  145. matching.  The <p> is a pattern (or names the file that contains
  146. the pattern and replacement) that is matched against each file
  147. line.  Case (upper or lower) is ignored unless the /x option has
  148. been taken.
  149.  
  150. A pattern is a string of characters.  We distinguish two kinds of
  151. characters:  normal and meta.  There are exactly nine
  152. metacharacters:
  153.  
  154.         . * + ? ^ $ [ ] \
  155.  
  156. The remaining characters are normal.  Metacharacters sometimes
  157. combine with normal characters as we will see.  Otherwise, a
  158. normal character simply matches itself.  The metacharacters
  159. behave as follows:
  160.  
  161.         A       matches
  162.         ─────   ────────────────────────────
  163.         .       any single byte
  164.         *       0 or more of the preceding
  165.         +       1 or more of the preceding
  166.         ?       0 or 1 of the preceding
  167.         [...]   any 1 of the enclosed bytes
  168.         [^...]  any byte not enclosed
  169.         ^       the beginning of the <cmp>
  170.         $       the end of the <cmp>
  171.         \α      α, where α is a metabyte
  172.         α\!ß    α or ß
  173.         \(α\)   α (grouped for precedence)
  174.         \δ      the δth group where δ is 1-9
  175.         \b      beginning/end of a word
  176.         \<      beginning of a word
  177.         \>      end of a word
  178.         \w      a word byte: [a-zA-Z0-9]
  179.         \W      a nonword byte: [^a-zA-Z0-9]
  180.  
  181. Note that the '\' metacharacter is used as an escape, i.e., to
  182. quote a metacharacter.  Thus to match, e.g., a period (as a
  183. normal character) you must use '\.'  If you leave out the
  184. backslash, the period alone will have its metacharacter meaning.
  185.  
  186. In the above explanation of the '*', '+' and '?' metacharacters,
  187. 'preceding' means 'the shortest possible preceding'.  Thus, 'ab+'
  188. matches 'ab', 'abb', etc., but not 'abab'
  189.  
  190. The square bracket metacharacters specify any one of the enclosed
  191. characters--known as a character class.  The minus sign has a
  192. special meaning as a range in a character class.  '[a-g]' can be
  193. used in place of '[abcdefg]'.  When appearing first in a
  194. character class, a circumflex indicates that the match is with
  195. any character not in the character class.  Thus, '[^0-9]' matches
  196. any non decimal-digit.  Most metacharacters lose their special
  197. status in a character class, and should not be escaped.  If a
  198. right square bracket is to be in a character class, it must
  199. follow immediately the beginning left square bracket.  If a minus
  200. sign is to be in a character class, it must appear as '---',
  201. i.e., a range containing only itself.  Since the square brackets
  202. do not nest, a left square bracket can easily be included in a
  203. character class.  E.g., '[][]' matches a right or a left square
  204. bracket.
  205.  
  206. Some pattern match examples follow:
  207.  
  208.         A                   matches
  209.         ────────────────── ───────────────────────
  210.         zyx                 zyx
  211.         f.x                 fax, fix and fxx
  212.         f\.x                f.x
  213.         f[aix]x             only fax, fix and fxx
  214.         \[[a-z]+\]          [hello] and [world]
  215.         \(suf\!pre\)fix     suffix or prefix
  216.         ba\(na\)*           banananana
  217.         [A-P]:              A:, C:, H:, etc
  218.         \([cd]:\)?\w        abc, c:zyx, d:cat, etc
  219.         \(abra\)\(cad\1\)*  abracadabracadabra
  220.  
  221.  
  222.     Due to a bug in PC DOS I have changed the alternative
  223.     (i.e., the "or") from '\|' to '\!'.  The vertical, '|',
  224.     is DOS's piping symbol.  Although doublequoting is
  225.     supposed to protect any redirection symbols in the
  226.     interior from being acted upon, under certain
  227.     circumstances DOS performs the redirection even though
  228.     it is doublequoted.
  229.  
  230. Please note that CHP's pattern matching is done via REGEX.C from
  231. Free Software Foundation, Inc.
  232.  
  233.  
  234. THE REPLACEMENT STRING:
  235.  
  236. The replacement string, <r> in the syntax diagram, uses only one
  237. metacharacter--namely the backslash.  The entire match is
  238. represented by \0.  The first group (a submatch) is represented
  239. by \1, the second by \2, through \9 for the ninth.  To represent
  240. a backslash as itself, you escape it by preceding it with a
  241. backslash.  A \l yields nothing but has the side effect of
  242. lowercasing the yield of the next backslash-digit pair.
  243. Similarly, a \u uppercases, and a \i initialcaps.  What about a
  244. backslash not followed by a digit, 'l', 'u', 'i', or a backslash?
  245. It disappears.  Other characters in the replacement string
  246. represent themselves.
  247.  
  248.     The \i upcases the first byte of each substring of
  249.     letters, and lowercases the remaining letters in the
  250.     substring.  A nonletter causes the next substring of
  251.     letters to be initialcapped.
  252.  
  253.  
  254. HEXADECIMAL REPRESENTATION IN PATTERN, REPLACEMENT
  255.  
  256. Sometimes it is convenient or necessary to represent bytes in a
  257. coded fashion.  You may need a smiley face, for example.  You can
  258. keyboard this character directly in two ways: (1) by entering a
  259. control-A, or (2) by holding down the ALT key, typing a "1" on
  260. the numeric keyboard, then releasing the ALT key.  But when you
  261. need to document this character on your printer, the smiley face
  262. does not print at all!  Worse yet, if you need to enter a tab on
  263. the DOS command line, DOS may translate it into spaces (up to the
  264. next tab stop).  CHP allows characters to be entered in a
  265. hexadecimal format, either as
  266.  
  267.         /xhh
  268.  
  269. or as
  270.  
  271.         \xh
  272.  
  273. where the h's are hexadecimal digits.  Both the "x" and the A
  274. through F can be upper/lower case (or mixed).
  275.  
  276. EXAMPLES:
  277.  
  278. To copy the file ALPHA.TXT to the new file JUNK while changing
  279. all occurrences of 'cat' to 'tiger', do a
  280.  
  281.         chp cat tiger alpha.txt>junk
  282.  
  283. The receiving file is well named because each occurrence of 'cat',
  284. irrespective of case, and regardless of surrounding material,
  285. will be changed.  The verify option will help a little, i.e.,
  286.  
  287.         chp/v cat tiger alpha.txt>junk
  288.  
  289. but I suspect that the Quit option will be taken after you start
  290. to find so many occurrences of 'cat' in other contexts.
  291.  
  292. To copy the file ALPHA.TXT to the new file JUNK while changing
  293. all occurrences of the word 'cat' (and not 'cats', 'cathode', or
  294. 'indicate') to 'tiger', do a
  295.  
  296.         chp \bcat\b tiger alpha.txt>junk
  297.  
  298. Note the '\b''s (i.e., wordbreaks) surrounding 'cat'.
  299. But wait.  What about the word 'cats'?  Shouldn't it be changed
  300. to 'tigers'?  Try
  301.  
  302.         chp \bcat\(s?\)\b tiger\1 alpha.txt>junk
  303.  
  304. Here the pattern may be paraphrased as a word that begins with
  305. 'cat' and ends with zero or one 's'.  Note that the zero or one
  306. 's' has been grouped in the funny backslashed parentheses.  This
  307. is to remember it in \1 which is used in the replacement string.
  308. Thus the word 'cats' does become 'tigers'.
  309.  
  310. Some occurrences of the word 'cat' (or 'cats') may begin a
  311. sentence, and others may be within a sentence.  I.e., at the
  312. beginning of a sentence, we have 'Cat', whereas 'cat' occurs
  313. within the sentence.  Correspondingly, we would like 'Cat' to
  314. become 'Tiger', and 'cat' 'tiger'.  That is what the /c CHP
  315. option is for.  E.g., if you invoke CHP with a
  316.  
  317.         chp/c \bcat\b tiger alpha.txt
  318.  
  319. which has the /c option,
  320.  
  321.         Cat, cat, burning bright,
  322.  
  323. is changed to
  324.  
  325.         Tiger, tiger, burning bright,
  326.  
  327. To change doublequotes into singlequotes with verification, do a
  328.  
  329.         chp/v "\"" ' alpha.txt >junk
  330.  
  331. The pattern seen by CHP in this case is simply one doublequote.
  332. The C compiler's argc-argv handler sees a doublequoted escaped
  333. doublequote.  The outer doublequotes are stripped, and the inner
  334. escaped doublequote becomes a doublequote.  The resultant
  335. doublequote is then given to CHP as the second command-line
  336. argument.  [The first argument is '/v'.]
  337.  
  338. Just for fun suppose you want to look at a file with all its
  339. vowels removed.  Try
  340.  
  341.         chp/d [aeiou] chp.doc
  342.  
  343. There is no replacment string here.  The /d option indicates
  344. deletion of the matched substrings.  The pattern consists of a
  345. character class containing the five vowels.  Because there is no
  346. redirection of stdout, the output will come pouring out on the
  347. screen just below the above CHP command line.  You might want to
  348. have BREAK ON (a DOS command) before you do this so that you can
  349. terminate CHP with a ^C.
  350.  
  351. Along a similar vein, how about removing all words containing
  352. 'th'?  To make it even more mystifying, we should also remove the
  353. character following each of these words (usually a space) so that
  354. there will be no obvious gaps.  This can be done to this document
  355. with a
  356.  
  357.         chp/dx \w*th\w*\W chp.doc
  358.  
  359. That pattern can be paraphrased as zero or more word constituents
  360. followed by 'th' (exact case because of the \x option) followed
  361. by zero or more word constituents followed by one nonword
  362. constituent.  Then, if you'd like to see the words that were
  363. removed, you can use the companion FP.EXE (Find Pattern) with a
  364.  
  365.         fp/hx \w*th\w*\W chp.doc
  366.  
  367.  
  368. How about removing the definite and indefinite articles, 'the',
  369. 'a' and 'an', from a file?  Try, e.g.,
  370.  
  371.         chp/d \b\(the\!an?\)\b\W chp.doc>junk
  372.  
  373. Perhaps you have a text file, JUNK1, wherein some lines have
  374. leading spaces, and some words are separated by multiple spaces.
  375. The leading spaces are to be deleted, and each internal
  376. multiple-space sequence is to be changed into a single space.
  377. These two changes cannot be done with a single invocation of CHP.
  378. However, the task can be done with a single DOS command line in
  379. which a CHP invocation is piped to another whose output is
  380. redirected to the resultant file, JUNK2.  The following DOS
  381. command line
  382.  
  383.         chp/d "^ +" junk1 | chp "  +" " " > junk2
  384.  
  385. does the job.  The first CHP specifies deletion of one or more
  386. leading spaces, the input file is JUNK1, and the output is piped.
  387. The second CHP's <p> specifies two or more spaces, the <r> is a
  388. single space, and the ouput is redirected to JUNK2.  Because it
  389. has no input file, the second CHP gets its input from (the piped)
  390. stdin.
  391.  
  392. Sometimes you need to exchange the order of pairs of words so
  393. that the second precedes the first.  This might occur in a data
  394. file in which names are in lastname/firstname order and you want
  395. them reversed.  Assuming the words are separated by a single
  396. space, the following pattern matches a pair of words putting the
  397. first in \1 and the second in \2.
  398.  
  399.         \(\w+\) \(\w+\)
  400.  
  401. Now, to copy the file NAMES.LST to the new file JUNK
  402. interchanging the word pair at the beginning of each line, do a
  403.  
  404.         chp/v "^\(\w+\) \(\w+\)" "\2 \1" alpha.txt>junk
  405.  
  406. The /v option is useful since it allows you to look at each match
  407. and at what is done to it.  If you don't like the first few, you
  408. can quit the operation.  If you like it, you can tell CHP to do
  409. the rest of the file without further verification (by responding
  410. with a ^R).
  411.  
  412. Interchanging last/first names reminds me of the all-caps NIH
  413. Telephone Directory.  It can be spruced up via CHP so
  414. that the names are initial-capped and are in forward order.
  415.  
  416.     The NIH Telephone Directory is available in machine
  417.     readable format under WYLBUR on the NIH IBM 370.  The
  418.     file can be downloaded to a PC.  Several LANs have copies
  419.     of it on the server's hard disk.  If you have access to a
  420.     copy, it is a good source file on which to practice with
  421.     patterns.  When first downloaded from the 370 all letters
  422.     are in uppercase.  Each line starts with an individual's
  423.     name, followed by spaces, followed by telepone number,
  424.     organization, building, and room number.
  425.  
  426. Each name is ordered as: last, first(s), initial(s), and JR, SR,
  427. II or III where applicable.  After each part is a single space.
  428. Some last names are in two words, the first of which might be MC,
  429. MAC, O, D, DI, DEL, VON, etc.  The name words need to be
  430. initialcapped (with the other letters lowercased).  This applies
  431. to JR and SR but not to II or III.  The single letter prefixes
  432. need to have the space that follows changed to an apostrophe.
  433. The MC's and the MAC's need to be closed up with the second part
  434. of the last name.  The last name (with any prefix) needs to be
  435. moved over beyond the first names and initials but before the JR,
  436. SR, II or III.
  437.  
  438. Here is a "listing" of TELEPHON.BAT that uses CHP to copy a file
  439. in the format of the NIH Telephone Directory into the format
  440. discussed above.
  441.  
  442.         ---------- TELEPHON.BAT
  443.         [1]:change O BRIEN to O'BRIEN, etc
  444.         [2]chp "^\([a-z]\) \([a-z]\)" \1'\2 %1 >%2_1
  445.         [3]:move JR/SR (initialcapped), II/III (no case change) over out of way
  446.         [4]chp \b\(\([js]r\W\)\!\(iii?\W\)\)\(\W+\) \4\i\2\3 %2_1 >%2_2
  447.         [5]:initialcap all name words
  448.         [6]chp ^\(\w+\W\)+\(\W+\) \i\1\2 %2_2 >%2_3
  449.         [7]:Close up MCs and MACs
  450.         [8]chp ^\(mac\!mc\)\(\W\)\(\(\w+\W\)+\)  \1\3\2 %2_3 >%2_4
  451.         [9]:move last name to end, recognizing prefixes
  452.         [10]echo ^\(\(\(d[iu]\!de[ls]?\!l[aeo]\!van\(\Wder?\)?
  453.             \!von\)\W\)?\)\([-'a-z]+\W\)\(\(\w+\W\)*\) >_tmpat_
  454.         [11]echo \6\1\5 >>_tmpat_
  455.         [12]chp/f _tmpat_  %2_4 >%2_5
  456.         [13]:move JR/SR/II/III back (from being moved over earlier)
  457.         [14]chp \(\W\)\(\W+\)\(\([js]r\!iii?\)\W\) \1\3\2 %2_5 >%2
  458.         [15]:TELEPHON.BAT  converts the nih telephone directory
  459.  
  460. There are six transformations.  The initial file, SAMPLE.UC in
  461. the example carried out below, is changed first to SAMPLE_1, then
  462. to SAMPLE_2, etc., finally emerging as SAMPLE.  The steps carried
  463. out are:
  464.  
  465.     1) Put the apostrophes in names like O BRIEN.
  466.  
  467.     2) Move II's, III's, JR's and SR's over out of
  468.        the way.  In the process JR's and SR's are
  469.        initialcapped, II's and III's are not.
  470.  
  471.     3) Initial cap the name words.
  472.  
  473.     4) Close up the MC's and the MAC's.
  474.  
  475.     5) Move last names to end, recognizing prefixes.
  476.  
  477.     6) Move Jr/Sr/II/III's back.
  478.  
  479. I have prepared a file, SAMPLE.UC, in the format of the NIH
  480. Telephone Directory.  I used my name plus modifications in it
  481. (including a fake doctorate) to show the various steps.  Here is
  482. the SAMPLE.UC:
  483.  
  484.     ---------- SAMPLE.UC
  485.  
  486.     D MAGNUSON ROBERT ANDRE II   496-6256  CR DMB     12A   4021
  487.     LE MAGNUSON BOB I            496-6256  CR DMB     12A   4021
  488.     MAC MAGNUSON ROBERT          496-6256  CR DMB     12A   4021
  489.     MAGNUSON ROBERT A            496-6256  CR DMB     12A   4021
  490.     MC MAGNUSON ROBERT SR        496-6256  CR DMB     12A   4021
  491.     O MAGNUSON ROB JR         DR 496-6256  CR DMB     12A   4021
  492.     VAN DER MAGNUSON R A         496-6256  CR DMB     12A   4021
  493.     VON MAGNUSON R ANDRE III     496-6256  CR DMB     12A   4021
  494.  
  495. I invoked TELEPHON.BAT with a
  496.  
  497.         TELEPHON SAMPLE.UC SAMPLE
  498.  
  499. which asks that SAMPLE.UC be transformed via the five
  500. intermediate files (which, in this case, are of the form
  501. SAMPLE_n), to the final SAMPLE file.  Appearing below in
  502. succession are the intermediate files, SAMPLE_1 through SAMPLE_5,
  503. and the final file, SAMPLE.
  504.  
  505.  
  506.     ---------- SAMPLE_1: Apostrophes inserted:
  507.  
  508.     D'MAGNUSON ROBERT ANDRE II   496-6256  CR DMB     12A   4021
  509.     LE MAGNUSON BOB I            496-6256  CR DMB     12A   4021
  510.     MAC MAGNUSON ROBERT          496-6256  CR DMB     12A   4021
  511.     MAGNUSON ROBERT A            496-6256  CR DMB     12A   4021
  512.     MC MAGNUSON ROBERT SR        496-6256  CR DMB     12A   4021
  513.     O'MAGNUSON ROB JR         DR 496-6256  CR DMB     12A   4021
  514.     VAN DER MAGNUSON R A         496-6256  CR DMB     12A   4021
  515.     VON MAGNUSON R ANDRE III     496-6256  CR DMB     12A   4021
  516.  
  517.     ---------- SAMPLE_2: Move over II/III's and
  518.                          (initalcapped) JR/SR's.
  519.  
  520.     D'MAGNUSON ROBERT ANDRE   II 496-6256  CR DMB     12A   4021
  521.     LE MAGNUSON BOB I            496-6256  CR DMB     12A   4021
  522.     MAC MAGNUSON ROBERT          496-6256  CR DMB     12A   4021
  523.     MAGNUSON ROBERT A            496-6256  CR DMB     12A   4021
  524.     MC MAGNUSON ROBERT        Sr 496-6256  CR DMB     12A   4021
  525.     O'MAGNUSON ROB         Jr DR 496-6256  CR DMB     12A   4021
  526.     VAN DER MAGNUSON R A         496-6256  CR DMB     12A   4021
  527.     VON MAGNUSON R ANDRE     III 496-6256  CR DMB     12A   4021
  528.  
  529.     ---------- SAMPLE_3: Initialcap name words:
  530.  
  531.     D'Magnuson Robert Andre   II 496-6256  CR DMB     12A   4021
  532.     Le Magnuson Bob I            496-6256  CR DMB     12A   4021
  533.     Mac Magnuson Robert          496-6256  CR DMB     12A   4021
  534.     Magnuson Robert A            496-6256  CR DMB     12A   4021
  535.     Mc Magnuson Robert        Sr 496-6256  CR DMB     12A   4021
  536.     O'Magnuson Rob         Jr DR 496-6256  CR DMB     12A   4021
  537.     Van Der Magnuson R A         496-6256  CR DMB     12A   4021
  538.     Von Magnuson R Andre     III 496-6256  CR DMB     12A   4021
  539.  
  540.  
  541.     ---------- SAMPLE_4: Close up the MC's and the MAC's.
  542.  
  543.     D'Magnuson Robert Andre   II 496-6256  CR DMB     12A   4021
  544.     Le Magnuson Bob I            496-6256  CR DMB     12A   4021
  545.     MacMagnuson Robert           496-6256  CR DMB     12A   4021
  546.     Magnuson Robert A            496-6256  CR DMB     12A   4021
  547.     McMagnuson Robert         Sr 496-6256  CR DMB     12A   4021
  548.     O'Magnuson Rob         Jr DR 496-6256  CR DMB     12A   4021
  549.     Van Der Magnuson R A         496-6256  CR DMB     12A   4021
  550.     Von Magnuson R Andre     III 496-6256  CR DMB     12A   4021
  551.  
  552.     ---------- SAMPLE_5: Move last name, recognizing prefixes.
  553.  
  554.     Robert Andre D'Magnuson   II 496-6256  CR DMB     12A   4021
  555.     Bob I Le Magnuson            496-6256  CR DMB     12A   4021
  556.     Robert MacMagnuson           496-6256  CR DMB     12A   4021
  557.     Robert A Magnuson            496-6256  CR DMB     12A   4021
  558.     Robert McMagnuson         Sr 496-6256  CR DMB     12A   4021
  559.     Rob O'Magnuson         Jr DR 496-6256  CR DMB     12A   4021
  560.     R A Van Der Magnuson         496-6256  CR DMB     12A   4021
  561.     R Andre Von Magnuson     III 496-6256  CR DMB     12A   4021
  562.  
  563.     ---------- SAMPLE: Move Jr/Sr/II/III's back.
  564.  
  565.     Robert Andre D'Magnuson II   496-6256  CR DMB     12A   4021
  566.     Bob I Le Magnuson            496-6256  CR DMB     12A   4021
  567.     Robert MacMagnuson           496-6256  CR DMB     12A   4021
  568.     Robert A Magnuson            496-6256  CR DMB     12A   4021
  569.     Robert McMagnuson Sr         496-6256  CR DMB     12A   4021
  570.     Rob O'Magnuson Jr         DR 496-6256  CR DMB     12A   4021
  571.     R A Van Der Magnuson         496-6256  CR DMB     12A   4021
  572.     R Andre Von Magnuson III     496-6256  CR DMB     12A   4021
  573.  
  574. Notes on TELEPHON.BAT:
  575.  
  576. Line [2] looks for a letter at the beginning of the line, a
  577. space, then another letter.  The result is the first letter, an
  578. apostrophe, then the second letter.  CHP's input file is %1, the
  579. output is %2_1.  In the example, these files are SAMPLE.UC, and
  580. SAMPLE_1.
  581.  
  582. In line [4] CHP looks for a word boundary, JR or SR followed by a
  583. nonword constituent, or II or III followed by a nonword
  584. constituent, then one or more nonword constituents.  The result
  585. is the one or more nonword constituents, an initialcapped copy of
  586. the JR or SR and its nonword constituent, then the II or III and
  587. its nonword constituent.  Although the result has both the JR/SR
  588. and the II/III, one of them is always null.  CHP reads SAMPLE_1,
  589. and DOS writes to SAMPLE_2 (substituting SAMPLE for %2 in the
  590. batch file).
  591.  
  592. In line [6] CHP looks for a sequence of one or more words
  593. anchored to the beginning of the line, each word of which is
  594. followed by exactly one nonword constituent.  Following the words
  595. the pattern wants a string of at least one nonword constituent.
  596. The result is an initialcapped copy of the words followd by the
  597. nonword constituent(s).  Here we went from SAMPLE_2 to SAMPLE_3.
  598.  
  599. In line [8] the pattern looks for MAC or MC anchored to the
  600. beginning of the line, exactly one nonword constituent, then a
  601. sequence of words each of which ends with exactly one nonword
  602. constituent.  The result is the MAC/MC, the sequence of words,
  603. then the space (i.e., the nonword constituent).  Thus, the MAC/MC
  604. is closed up with the rest of the last name, and the removed
  605. space is placed after the rest of the name (to preserve the
  606. original length of the whole name).  The input file is SAMPLE_3,
  607. the output, SAMPLE_4.
  608.  
  609. In line [12] CHP is invoked with the /f option whereby the
  610. pattern and the result are read from a file--named _TMPAT_ in
  611. this case.  The ECHO in line [10] writes the pattern to _TMPAT_,
  612. and the ECHO in line [11] appends the result parameter to
  613. _TMPAT_.  The task here is to put the first name(s) and initials
  614. ahead of the last name.  Usually the last name is the first word
  615. on the line, but the last-name prefixes have to be taken into
  616. account.  An inspection of the current NIH telephone directory
  617. revealed the following prefixes: Di, Du, De, Del, Des, La, Le,
  618. Lo, Van, Van De, Van Der, and Von.  (I hope I didn't miss any.)
  619. The pattern specifies that zero or one of these (with its
  620. trailing blank) occurs at the beginning of the line, a word of
  621. one or more letters, apostrophes or hyphens (i.e., the last
  622. name), then a sequence of words (the first names/initials) each
  623. with its trailing blank.  The result is to be the first
  624. names/initials, the possibly null prefix, then the last name.
  625. SAMPLE_4 is copied with the changes to SAMPLE_5.
  626.  
  627. Finally, in line [14], the JR/SR/II/III's are moved back creating
  628. the final file, SAMPLE.
  629.  
  630.