C-Kermit's CHANGE Command
Frank da Cruz
January 30, 2016
Last update:
Sun May 8 20:16:58 2022 (format)
The CHANGE command, new to C-Kermit
9.0.304, lets you replace strings in one or more text files with new
strings in a way that is more convenient and less error-prone than changing
each file by hand, and is more portable and flexible than using a Unix
sed script or other platform-specific method.
Suppose (for example) you manage a website with thousands of files in a
directory tree, many of which link to an offsite page whose URL has just
changed. Now you can fix them all with a single C-Kermit command:
change /recursive ~/web/*.html www.oldname.com www.newname.com
The syntax of the CHANGE command is:
CHANGE [ switches ] filespec String1 [ String2 ]
The CHANGE command replaces all occurrences of
string1 with
string2 in the specified file or files. It works line by line; it
does not do multiline or across-line substitutions (you can use the
replacetextblock script for that). To
remove strings from files, specify
string2 as
"" or
omit
string2. The filespec and strings can be given literally or you
can use variables for them.
Square brackets indicate switches (explained
below) that are optional. The filespec is a "file specification",
which can be the name of a single file, possibly with a relative or absolute
path included, or a "wildcard" pattern that uses special characters to match
filenames, such as "*.html" to match all HTML files (see below for details about wildcards).
String1 and String2 should be enclosed in doublequotes
"" or braces {} if if they contain spaces; for
example, to update the copyright notice in a collection of C-language
source files:
change *.[ch] "Copyright (C) 1985, 2015" "Copyright (C) 1985, 2016"
In the event that String1 or String2 already contain braces or doublequotes,
especially if these are not balanced, some quoting may be required. Or you
can assign the strings to variables and then use the variable names in the
CHANGE command; example:
.a = {value="./
.b = {value="../
change *.html \m(a) \m(b)
Since the CHANGE command works line by line, only text files can be
changed; C-Kermit automatically skips over binary files.
How the CHANGE command works
For each text file that matches the given
filespec, the CHANGE
command reads the original file line by line, changing all occurrences (if
any) of
String1 to
String2 in each line, and writing the
result to a result file.
Normally the result file is a temporary file, which is then renamed
back to the original file's name, thus overwriting it. Other options explained below allow you to back up the original
file or to write the result file into a different directory. Each of these
options preserves a copy of the original file.
Temporary files are created in the directory indicated by Kermit's
\v(tmpdir) variable (“show var tmpdir”). If the
temporary directory does not exist, or none is specified, you'll get an
error message. You can specify a temporary directory with the SET
TEMP-DIRECTORY command, or by setting a environment variable (Unix) or
symbol or logical name (VMS) such as TMP, TEMP, or TEMPDIR to the full path
of the desired directory, to which you must have write access. If you
haven't defined a temporary directory or an environment variable for this,
C-Kermit uses the underlying operating system's convention, such as
the /tmp directory in Unix.
All temporary files are deleted after use.
Switches
In Kermit's command language a
switch is an optional command field
that lets you modify the normal or
default behavior of the command.
The CHANGE command has lots switches:
/after: /destination: /modtime: /recursive
/backup: /dotfiles /nodotfiles /simulate
/before: /except: /norecursive /smaller-than:
/case: /larger-than: /not-after:
/count: /list /not-before:
...for file selection (size, date, exception lists, dot-files), file
disposition, directory traversal (flat or recursive), modification time of
changed files (updated or preserved), and reporting of results.
File selection switches
These are handy when your file specificion is “wild”; that is,
it contains wildcard characters and match more than one file. In the
absence of instructions to the contrary, C-Kermit changes all the text files
in the specified or current directory that match your file specification and
that contain at least one instance of
String1. But you can refine
the selection using these switches in any desired combination:
- /after:date-time
- Only process files created or modified after the given date and time,
which can be in almost any format, provided there are no embedded spaces, or
if there are, that is is enclosed in doublequote or braces.
Synonym: /since:. Examples:
/after:21-jan-2016_12:00:00
| Contains no spaces
|
/after:"21 jan 2016 12:00:00"
| Contains spaces, use quotes
|
/after:{jan 21, 2016 12:00}
| Contains spaces, use braces
|
/after:"jan 21, 2016"
| No time is given, 0:00:00 is assumed
|
/after:1/21/2016
| No time is given, 0:00:00 is assumed
|
/after:21/1/2016
| 21 is always a day, not a month
|
/after:YESTERDAY
| Symbolic date
|
/after:8:00
| No date given; current date assumed
|
/after:8:00pm
| AM or PM can be specified
|
/after:20:00
| Military time format can be used
|
/after:"TODAY +7days"
| offsets can be specified
|
etc etc. For complete details about C-Kermit's date/time formats,
CLICK HERE.
- /before:date-time
- Only process files created or modified before the given date and
time.
- /not-after:date-time
- Only process files created or modified on or before the given
date and time. Synonym: /not-since:.
- /not-before:date-time
- Only process files created or modified on or after the
given date and time.
- /dotfiles
- (Unix only) Do not skip files whose names begin with a period (.).
Normally they are skipped.
- /nodotfiles
- (Unix only) Do not process files whose name begins with a period
(.). This is the default action.
- /except:filespec
- Do not process files whose names match the given pattern;
for example /except:old*.txt. The filespec can be the
name of a file or a character string containing wildcards such as
“*”, which matches any sequence of characters.
It is also possible to specify a list of patterns or files to be excluded.
See below for more about wildcard syntax.
- /larger-than:number
- Only process files that are larger than the given number of bytes
(characters).
- /smaller-than:number
- Only process files that are
smaller than the given number of bytes.
- /recursive
- Process not only the files in the current directory, but also the files
in all the subdirectories of the current directory, and all the
subdirectories of the subdirectories, and so on. In other words, process
all files that meet the other criteria in the entire directory tree rooted
in the current directory.
- /norecursive
- Process only files in the current (or specified) directory that meet the
all the other given criteria, which is the normal procedure.
File disposition switches
Normally the CHANGE command modifies files in place; unless you tell
Kermit otherwise, each original file that is modified by the CHANGE command
is
replaced by the changed version. If you wish to preserve the
original files, two options are available:
- /backup:directory-name
- This lets you specify the name of a directory where a copy of each
original file is to be stored. The CHANGE command then uses this directory
to back up each file that is changed. The backup directory may not be the
same as the destination directory (if any) or the source directory.
- /destination:directory-name
- This lets you specify the name of a directory where the new (changed)
files will be stored. In this case, the original files stay where they are,
the the changed files go into tbe specified directory, and no temporary files
or directories are used. The destination directory may not be the same as
the backup directory (if any) or the source directory.
These two switches are not mutually exclusive; you can use them both,
in which case the original file stays as it is, the changed file appears
in the destination directory, and a copy of the original file appears
in the backup directory.
- /modtime:{preserve, update}
- Determines the modification timestamp for a file that is changed;
"preserve" means to keep the file's original modification timestamp;
"update" (which is the default action) means to set the file's modification
timestamp to the date and time at which it was modified by the CHANGE
command, but only if it was modified. Files that do not contain
the search string (string1) are not disturbed in any way.
String selection switches
- /case:{on,off}
- When searching for strings to replace, require alphabetic case
to match (ON), or ignore alphabetic case (OFF). The default action is
ON, which requires the case of each letter to match. Thus "Hello"
matches "Hello" but not "hello".
Action switches
- /count:variablename
- Sets the value of the given variable to the number of files that were
changed.
- /list
- Reports which files are being changed. Without this switch
the CHANGE command operates silently.
- /simulate
- Reports which files that would be changed without changing them.
Using switches
CLICK HERE to read complete details of the
syntax and use of switches. But in brief...
Switches must be separated from other command fields and each other by blank
space. There must not be any blank space between a switch and its argument.
If a switch argument contains any spaces, it must be enclosed in
doublequotes or braces. Switches can be combined in any desired manner, for
example:
change /before:1-feb-2016 /not-before:1-jan-2016 *.txt December January
changes all occurrences of the word “December” to
“January” in all files having modification timestamps in January
of 2016.
If you include the same switch more than once in a single CHANGE command,
the value of the last instance is used.
Lots of C-Kermit's other file transfer and management have the same or
similar switches: SEND, GET, DIRECTORY, DELETE, COPY, RENAME, TOUCH, and so on.
C-Kermit's wildcard syntax
CLICK HERE for a thorough description
description of C-Kermit's wildcards and pattern matching tools, with
examples. But in brief...
A “wildcard” is a notation used in a filename to match multiple
files. For example, in “send *.txt” the
asterisk is a wildcard, the meaning in this case is “send all files in
the current directory whose name ends with .txt”. Most
Kermit commands that accept filenames also accepts wildcards, the exception
being commands that are allowed to operate on only one file, such as
TRANSMIT. C-Kermit accepts the following wildcards:
*
| (asterisk or "star")
Matches any sequence of zero or more characters. For example, "ck*.c"
matches all files whose names start with "ck" and end with ".c"
including "ck.c".
|
?
|
(question mark)
Matches any single character. For example, "ck?.c" matches all files whose
names are exactly 5 characters long and start with "ck" and end with ".c".
When typing commands at the prompt, you must precede any question mark to
be used for matching by a backslash (\) to override the normal
function of question mark in interactive commands, which is to provide
menus and file lists. You don't, however, need to quote filename question
marks in command files (script programs).
|
[abc]
| Square brackets enclosing a list of characters matches any character in
the list. Example: ckuusr.[ch] matches ckuusr.c and
ckuusr.h.
|
[a-z]
| Square brackets enclosing a range of characters matches any character
in the range; a hyphen (-) separates the low and high elements of
the range. For example, [a-z] matches any letter from a to z.
|
[acdm-z]
| Lists and ranges may be combined. This example matches a, c, d, or any
letter from m through z.
|
{string1,string2,...}
| Braces enclose a list of strings to be matched. For example:
ck{ufio,vcon,cmai}.c matches ckufio.c,
ckvcon.c, or ckcmai.c. The strings
may themselves contain *, ?, [abc],
[a-z], or other lists of strings.
|
To force a special pattern character to be taken literally, precede it with
a backslash, e.g. [a\-z] matches a, hyphen, or z rather than a
through z. Or tell Kermit to SET WILDCARD-EXPANSION OFF before entering or
referring to the filename (but then set it back ON afterwards to restore the
normal behavior).
Similar notation can be used in general-purpose string matching; for example
in the IF MATCH command:
if match ckufio.c {{ck[cuw]*.[cwh],makefile}} {
echo "It's a C-Kermit source file"
}
Type HELP PATTERNS at the C-Kermit prompt for details. Also see HELP SET
MATCH.