============================================================================ || || || MAT -- p.n.; poss. abbrev. of "Match"; also "Matte" [Motion || || Picture Arts]: means of cutting, inserting and superposing || || disparate items. || || || || ------------------- || || || || This program provides a flexible string-searching, pattern-matching || || and substitution mechanism for both text and filenames. Searching || || for a string in a file is fast (it can be three times as fast as the || || AmigaDOS 'SEARCH'). The (much slower) matching scheme is an extended || || version of the standard AmigaDOS pattern-matching convention, with || || the added features of negation and "slicing" of matched strings. It || || will probably be most useful within command (or ARexx) scripts to || || extend the operations possible with AmigaDOS. || || || || || || || || * Searches for strings or patterns within text files. || || || || * Rearranges text within matched lines to || || create new files. || || || || * Tags and labels can be added to the output stream || || at desired points || || || || * Searches directories for matching file names. || || || || * Creates Command Script Files by inserting the whole or || || parts of matched filenames into text templates. || || || || * Control commands for the program may be read from a || || script file as well as the command line. || || || || || || -- Copyright 1990 Peter J. Goodeve -- || ============================================================================ -- by Pete Goodeve -- July 1990 Overview ________ This program is intended to fill a number of pattern matching needs not covered by other facilities. It is very flexible, and consequently has a number of features you may never use, but it is well suited to those everyday jobs, too. It handles both string searches (in which the string will be found anywhere it occurs on the lines being scanned), and pattern matches that compare each whole line against a pattern. String searches can be at least three times as fast as if you used the AmigaDOS 'SEARCH' (disk access time may well limit the improvement, though). Pattern matches are much slower of course, but provide much more precise control of the operation. You can also often get the best of both by "filtering" the text first with a string search and applying the pattern only to those lines that contain the filter string. Patterns are in the usual AmigaDOS format (as used by LIST and so on), with a number of extensions. You can specify "negative match" segments, whose appearance will cause a match to fail, and you can -- most importantly -- indicate "slice points" that mark pieces of the matched string to be rearranged in the output. To illustrate: MAT S #include mysrc.c would print out all lines that contain the string "#include" in the file "mysrc.c". Note that a) the keyword argument "S" signals that this is a string search (you can also use the full keyword "SEARCH" -- upper or lower case); b) the string can be anywhere in the line (though this particular one will usually be at the beginning); and c) the character '#' has no special meaning in a string search (as opposed to being a special character in a pattern). MAT S #include #?.c would do the same thing for all files in the current directory ending in ".c". You can have several file specifications in one command if you like: MAT S #include test/#?.c WORK:#?/#?.c would search all such files in the subdirectory "test" and all (immediate) subdirectories of assigned device "WORK:". The preceding examples simply display all lines that fit the criterion, but you can add a "template" to specify exactly what should be output. MAT S #include T "^F line ^N: ^O" #?.c Here, the addition of the template, with its preceding keyword "T" (or full word "TEMPLATE"), specifies that each matching line should be displayed in this fashion: "mysrc.c line 5: #include " The marker "^F" (two characters -- the caret '^' followed by upper case 'F' -- NOT a "control-F") indicates that the current file name should appear here; "^N" represents the current line number, and "^O" ("Oh", not "zero") indicates the original current line. There are a number of other template markers you can use, especially when you are matching against a "slicing pattern" rather than doing a string search. You can also specify a template for all the lines that FAIL to match. In addition to templates, which apply to every line, you can supply a "Tag", which applies once per file -- immediately before the first matched line if there is one, otherwise when the whole file has been read (giving an alternative message). The format is the same as a template. MAT S #include TAG "^F:^| No matches found in ^F" #?.c will display the filename (once) before all lines matched in that file, or, if there were no matches, report that fact. The "^|" pair separates the 'success' and 'failure' portions of the tag (or template). Pattern matching can be done on the lines of a file in much the same way. MAT "#?printf#?,# X,#?" mysrc.c looks for any lines that do a "printf" on variable "X" (with arbitrary characters intervening. (Notice that no keyword is needed here, as this is the default case, but if you prefer you can use the key "P" or "PAT"; for variant forms, or where there is ambiguity, a keyword may be required.) You can speed things up by screening the lines first: MAT S printf P "#?printf#?,# X,#?" mysrc.c only does the full match on lines that contain printf. The keyword "P" is needed here to make your intention clear. You can add "slice-marks" to a pattern, and rearrange the resulting pieces with a template. The slice-mark is a single caret character placed at the desired point. (When you use slice marks, you must also use a template.) MAT #?^(word|another)^#? "^1: ^0----^2" myfile Here slice marks are placed either side of the bracketed alternation in the pattern. In the template,"^0" is the segment of the line matched by the part of the pattern before the first slice mark, "^1" is the segment between the two marks (i.e. "word" or "another", depending on which was matched), and "^2" is the rest of the line. Thus, if the input line was "this line contains the word we are looking for" the output would be "word: this line contains the ---- we are looking for" Up to this point, the examples have focussed on scanning text files, but the same mechanisms can equally well examine directories. For the simple jobs, of course, one would just do a DIR or LIST, or perhaps a LIST...LFORMAT.., but Mat can do a few things that the others can't. For instance, the ability to exclude files by means of a "negative match" can be very useful. Also the template is rather more flexible than that of "LIST..LFORMAT (and pre-dates it by about three years!), among other things allowing specifiers for directory-path separate from the filename. For example, for taking quick looks at a bunch of files, I have a script that does something like this (although in fact it also pops up a new full-screen window to do it in, and uses a PIPE:): .K filepat/A MAT >T:_mm T "more ^P" F execute T:_mm "^P" represents a complete pathname, and the keyword "F" (or "FILES") says that the file names (specified in the filepat argument) are to be used themselves, rather than be scanned. The preceding example is similar to the "DPAT" script that comes with 1.3, but you can do other things, too. Suppose (and I have actually been in this situation) that I have a bunch of files that I have previously renamed to "myfile.c_0", "myfile.o_0", "myfile_0" and so on, which I now want to restore to their former names by chopping off th "_0". I have a script that calls Mat in a similar way to the above, and does just what I want: REN myfile#?^_0 AS ^0 The first argument to the script is a pattern to select the files to be renamed, and the second is the template specification of the new names. Notice the "slice-mark" '^' in the pattern, and the marker "^0" (meaning the part to the left of the slice) in the template. Without bothering to detail the script, the core is a Mat command line that creates appropriate "RENAME" commands to be executed. In most cases you will want to have Mat embedded in script files, as this can drastically simplify the otherwise sometimes complex syntax. Mat, by the way, returns a "WARN" value (5) to AmigaDOS if no match was found -- useful for conditional execution in scripts. This has only been a brief sketch of the various modes and so on that the program has. It is worth bearing in mind though that it has a number of features -- including the possibility of accepting commands from a script file or pipe -- that add to its usefulness in things like installation scripts. These features also let it work well with ARexx (even though it doesn't itself have an ARexx port). The following sections go into more detail about Mat's capabilities. First the command line formats and operating modes are described, then the keywords are listed in detail. Following this is a full description of AmigaDOS-type patterns in general, and the extensions used in Mat. Finally comes a discussion of Templates and File Specifiers. + + + + + Installation and Operation __________________________ Mat is like any other CLI/Shell command, and is invoked by a command line with suitable arguments. For normal use it should be available in the C: directory (or at least on the path of the current shell). For added speed (under AmigaDOS 1.3 or later) it may be made Resident. Command Line Arguments ______________________ There are a number of basic command forms corresponding to the various operations Mat can perform. Each of these in turn can have variants, and they can often be combined to achieve a particular result. There are several common basic components, however, which first need clear understanding. In the order they normally appear in the command line, from left to right, they are: , ,