yelt: a stream text editor similar to sed but with more internal variables,
user definable functions, escape sequence handling, cut program
and tr program features, and simplified parsing support.
For more information, see http://www.bordoon.com/yelt
Invocation:
yelt [options] [files]
options:
-f file use script specified in file
-S string use script specified in string
-e cmd add 1 extension command to the default script
-l turn on diagnostic logging
-M file define string mapping file
-D char set the map file delimiter for key/value pairs
Yelt's Default script:
w { n; [ -e extensions ] ; p; }
Where this script means:
Repeatedly read the next line, execute any
user supplied commands (ie -e options) and print each line.
Writing scripts:
Don't forget to put your own 'w { n; ... p; }' wrapper
in your script file or your -S option string!
Comments may be added to script files by adding lines that
begin with the # character. These are the only comments supported.
The map file is optional and defines the mapping for the 'M' command.
The -M option may be used multiple times and the delimiter option. -D
can also be used multiple times: use -D before -M.
If the option, '-f -' is specified, then the script is read
from stdin.
Script language overview
Yelt's command language is very similar in look and feel to that
of SED. Yelt has more variables and different commands, but it is
very SED-like. The commands that yelt supports also have an
assembly language look and feel: the names are terse and registers
upon which to operate are part of the command. Commands come in
0-register, 1-register, 2-register, and 3 register variants.
Yelt commands should usually be terminated by ;'s. Here are some
quick examples:
a01; p3; A98; x34; q3 stuff; L9; l1; A19;
Note: for 1-register commands, if the register is 0, you can leave it out:
the command, 'p;', prints register 0.
Simple Commands:
Note that variable numbers listed below are just examples
There are 10 variables available for any use. They are numbered
0-9.
n -- read the next line of input into variable 0.
If end of file, get out of the current loop.
n3 -- read the next line of input into variable 3
R4[d] [f]-- read an entire file into a register. The register
must be specified immediately after the letter R.
The file's name can be specified in either of two
ways -- either as a second register number or as a
separate token in the command ([f]). The entire
file will be read into the register variable with
embedded new line characters. Use SC, SR, or SW
to split it up -- if needed. If no filename is
specified -- either as a second register number or as
a filename, then stdin will be read.
p -- print variable 0
p2 -- print variable 2
a01 -- copy variable 0 into variable 1
A01 -- append variable 0 into variable 1
x49 -- swap variables 4 and 9
q9 X -- copy string 'X' into variable 9
(note: to inject ; use \;). ; is the terminator
leading and trailing blanks are removed so use \s
to force spaces.
l3 -- put the current line number into variable 3
L9 -- put the current file name in variable 9
j3 W -- justify variable 3 to the left for a width of W
J1 W -- justify variable 1 to the right for a width of W
+8 -- increment variable 8
-3 -- decrement variable 3
M9! -- map variable 9 through the table defined by the -M option
That is, convert variable 9 into its mapped value.
The ! is optional and means the following: if there is no
mapping found, leave the variable alone.
t4 -- expands tabs in variable 4
SW012 =+@ -- splits variable 0 into three parts, keeping the left side in
variable 0 and moving the right hand side into variable 2.
The character from the delimiter list, '=', '+', or '2' will
be left in register variable 1.
The =+@ characters are a string whose contents defines
delimiters on which the split occurs. The delimiter
actually found is removed in the process and does not appear
in variable 1. To use space as a delimiter, use \s.
SC94 10 -- similar to the SW command but splits based on character
counts. Variable 9 is reduced in size to the first 10
characters, and the deleted characters are moved into
variable 4.
SR012 /r/-- split the string in variable 0 into 3 pieces:
the part up to but not including the regular expression, r
is left in register 0.
the part that matched the expression is stored in register1
the part after the match is left in register 2
c2 20-39 -- cuts out all the data in variable 2 except for the text
in columns 20 through 39, inclusive. Column 20 then
becomes column 1.
W75 -- write the contents of variable 7 to the file whose name
is found in variable 5.
String substitutions:
s/a/b/g -- substitute in variable 0, all a's with b'
s/c/d/1 -- substitute only the first c with d in variable 0
s3/e/f/g -- substitute all e's in variable 3 with f's
Note: The first string in a substitution is a grep style
regular expression: meaning that you must use
\( ... \), not ( ... ), for grouping. You must
use \+, not just + to force at least one repetition
and \ escapes almost everything else.
The second string in substitution command is mostly
just plain text, but you can use the following special
sequences: & means the entire text pattern matching
the regular expresion.
\0 is the same as &
\1-9 refers to the part of the source text
that matched a \( \) in the regular
expression. The number is the count of \('s
from the beginning of the regex (starting
with 1.
\& injects & into the output
\~0-9 injects the contents of variable 0-9
into the output.
Other delimiters besides / can be used in the s command, they are:
| : # ?
To insert control codes or special characters into the
output using a substitution, use one of the following
escape sequences in the RHS of the substitution:
\n -- newline
\t -- tab
\s -- space
\b -- backspace
\a -- bel
\r -- carriate return
\e -- escape
Conditions and program control:
{cmd ; cmd} -- execute multiple commands in a block
if /r/ c [else x] -- if regex matches, execute cmd c, else executed command x
w{ cmds } -- repeatedly execute cmds until end of file
use 'n' or 'b' or 'd' to getout of the loop.
b -- break out of the while loop you are in
d -- continue with the loop but skip the rest of
current iteration thereof
Q -- quit the entire script
1,5cmd -- execute cmd only in lines 1 through 5
40,$ cmd -- execute cmd on all lines 40 and higher
20,/r/ cmd -- execute cmd on lines after 20 until the line containing
/r/ -- inclusive
/stuff/cmd -- execute cmd only if variable 0 contains stuff
/r/,/s/ cmd -- execute cmd if curline in range /r/ to /s/ where
r and s are regular expressions defining a group of lines.
The line containing /s/ is executed unless the cmd checks
for that and doesn't execute. For example:
/r/, /s/ { /s/! cmd; }
/r/ and /s/ apply to the same variable (defined in /r/~[digit])
/r/,90 cmd -- execute cmd on lines starting with the first line to contain
/r/ until line 90 -- inclusive
/r/,$ cmd -- execute cmd on all lines after the first containing /r --
inclusive.
/x/!cmd -- execute cmd only if variable 0 does no have x in it
/y/~3cmd -- execute cmd only if varible 3 has a y in it
/z/~4!cmd -- execute cmd only if variale 4 has no z's in it
F3 {script} -- Open the file whose name is in variable3 and apply
the script to it -- you must use the n and p commands
in the script if you want actually process the text.
|31!cmd -- execute cmd if the text in variable 1 matches the regex
stored in variable 3. The ! is optional and if given
it means that the command will execute if the current
line does NOT match the regex in var 3.
Functions
C fun 1,3; -- Call function 'fun' passing registers 1 and 3 to that
function which will use them as its registers 0 and 1
then return any data to the caller back in the caller's
registers 1 and 3.
Def fun 2; -- Declare function 'fun' which accepts 2 registers as
parameters and which will return any values in those same
registers. See the function's comments.