LevSelector.com |
intro | home - top of the page - |
awk - text-processing programming language very common on Unix. It is named after its three original authors: (Alfred V. Aho, Brian W. Kernighan, Peter J. Weinberger).
There are many tutorials and FAQs - search google for awk tutorial or awk faq.
• www.engin.umich.edu/htbin/mangate?manpage=awk - awk manpage
Learn awk in just 1 hour
- using this tutorial (adapted from adaptation from ... from original author
: Brian Brown, CIT, 1994).
Here is a typical example of usage - and comparison with perl one-liners.
1. ps -ef | awk '/-tcsh/ {print $0}'
ps -ef | perl -ne 'print if /\-tcsh/;' 2. ps -ef | awk '/vi/ {print $(NF-1) " " $NF}'
|
Usually an awk program processes input lines by applying pattern and
doing some action. Thus the program consists of a number of patterns and
associated actions. Actions are enclosed using curly braces, and separated
using semi-colons.
pattern
{ action }
pattern
{ action }
awk uses special characters $0, $1, $2, etc.:
$0
- entire input line
$1
- first field (word)
$2
- second field
etc.
Fields are separated by a space or tab character. For example the line
"I like money." will be presented as follows:
$0
- I like money.
$1
- I
$2
- like
$2
- money.
Your first awk program
{
print $0 }
There is no pattern to match, only an action - which will work for
every input line and will simply print it out.
We can put this simple 1-line program in a file "myawk1"
and then type the following on the prompt:
awk
-f myawk1 /etc/group
awk will apply commands in file "myawk1"
to each line of input file /etc/group. The effect is to print
out each input line read from the file, in effect, displaying the file
on the screen (same as the Unix command cat).
Now let's apply simple pattern, for example, only print lines with the
word "brian" in them:
/brian/
{ print $0 }
Now let's output only 2 first words:
/brian/
{ print $1, $2 }
Using awk with pipe:
who
| awk -f myawk1
awk is good to extract info from "form" files (means - when information is presented in columns separated by some white space). For example, if file awktext contains the following:
Type Memory (Kb) Location
Serial # HD Size (Mb)
XT 640 D402 MG0010 0 386 2048 D403 MG0011 100 486 4096 D404 MG0012 270 386 8192 A423 CC0177 400 486 8192 A424 CC0182 670 286 4096 A423 CC0183 100 286 4096 A425 CC0184 80 Mac 4096 B407 EE1027 80 Apple 4096 B406 EE1028 40 68020 2048 B406 EE1029 80 68030 2048 B410 EE1030 100 $unix 16636 A405 CC0185 660 trs80" 64 Z101 EL0020 0 |
Then let's print out only lines with Type == "386":
$1
== "386" { print $0 }
Note: The == symbol represents an equality test (not matching
a part).
Puting this one-line program in a file myawk2 and running it like this:
$
awk -f myawk2 awktext
Output:
|
Comments: comments begin with the hash (#) symbol and continue
till the end of the line.
Example:
$1
== "386" { print $0 } #
print all records where the computer is a 386
Remember that the comment ends at the end of the line. The following
program is thus wrong, as the closing brace of the action is treated as
part of the comment.
$1 == "386 { print
$0 #print out all records }
Relational operators which can be used in comparing expressions.
< less than
< = less than or equal to == equal to != not equal > = greater than or equal to > greater than ~ matches !~ does not match |
Example:
#
myawk4, an awk program to display all input lines for computers
# with less than 1024 Kb of memory $2 < 1024 { print $0 } Output: XT 640 D402 MG0010 0 "trs80" 64 Z101 EL0020 0 |
Example:
#
myawk5
# an awk program to print the location/serial number of 486 computers $1 == "486" { print $3, $4 } Output: D404 MG0012 A424 CC0182 |
Example:
#
myawk6
# an awk program to print out all computers belonging to management. /MG/ { print $0 } Output: XT 640 D402 MG0010 0 386 2048 D403 MG0011 100 486 4096 D404 MG0012 270 |
Improved - check for MG only in the 4th column:
$4 ~ /MG/ { print $0 } |
Examples:
$2
!= "4096" { print $0 }
$5
> 100 { print $4 }
$4
!~ /CC/ { print $0 }
Example of more detailed output:
#
myawk7
# list computers located in D block, type and location $3 ~ /D/ { print "Location = ", $3, " type = ", $1 } Output: Location = D402 type = XT Location = D403 type = 386 Location = D404 type = 486 |
Formatting output using printf (like in C, terminate with a semi-colon. Brackets are used to enclose the argument, and the text is enclosed using double quotes:
#myawk8
$1 == "286" { printf( "Location : "); print $3 } Output: Location : A423 Location : A425 |
Example of a string format:
#myawk9
$1 == "286" { printf( "Location is %s\n", $3 ); } Output: Location is A423 Location is A425 |
Example - %s format:
#myawk10
$1=="286" { printf( "Location = %s, serial # = %s\n", $3, $4 ); } Output: Location = A423, serial # = CC0183 Location = A425, serial # = CC0184 |
Example - %d format:
#myawk11
$1=="486" { printf("Location = %s, disk = %dKb\n", $3, $5 ); } Output: Location = D404, disk = 270Kb Location = A424, disk = 670Kb |
Example - %s format with specified width:
#myawk12
# formatting the output using a field width $1=="286" {printf("Location = %10s, disk = %5dKb\n",$3,$5);} Output:
|
Summary of printf so far
%[n]s
print a text string
%[n]d
print a numeric value
\n
print a new-line
The keywords BEGIN and END are used to perform specific actions before and after reading the input lines. The BEGIN keyword is normally associated with printing titles and setting default values, whilst the END keyword is normally associated with printing totals.
Example:
#myawk13
BEGIN { print "Location of 286 Computers" } $1 == "286" { print $3 } Output:
|
Pre-defined variables, for example:
NR
- the current input line number
NF
- number of fields in the input line
Example:
#myawk14
# print the number of computers END { print "There are ", NR, "computers" } Output:
|
User-defined variables:
Default value - always zero.
The following awk program counts the number of 486 computers,
and uses the END keyword to print out the total after all input
lines have been processed. When each input line is read, field one is checked
to see if it matches 486. If it does, the awk variable computers
is incremented (the symbol ++ means increment by one).
#myawk15
$1 == "486" { computers++ } END { printf("The number of 486 computers is %d\n", computers); } Output:
|
Part 2 or 3 | home - top of the page - |
Regular Expressions - pattern searching
similar to grep and other unix utilities:
/386/
$1 ~ /386/
In regular expressions, the following symbols are metacharacters with
special meanings.
\ ^ $
. [ ] * + ? ( ) |
^
matches the first character of a string
|
A group of characters enclosed in brackets matches to any one of the enclosed characters. In the example below (myawk16), field one is matched against either "8" or "6".
#myawk16, display all x8x
computer types
$1 ~ /[86]/ { print $0 } Output:
|
Note: In this example, field one is searched for the character '8' and '6', in any order of occurrence and position.
If the first character after the opening bracket ([) is a caret (^) symbol, this complements the set so that it matches any character NOT IN the set. The following example (myawk17) shows this, matching field one with any character except "2" "3" "4" "8" or "6".
#myawk17
# display all which do not contain 2, 3, 4, 6 or 8 in first field $1 ~ /[^23468]/ { print $0 } Output:
|
#myawk18
# display all lines where field one contains A-Z, a-z $1 ~ /[a-zA-Z]/ { print $0 } Output:
|
Parentheses are used to group options together, and the vertical bar is used for alternatives. In the following example (myawk19), it searches all input lines for the string "Apple", "Mac", "68020" or "68030".
#myawk19
# illustrate multiple searching using alternatives /(Apple|Mac|68020|68030)/ { print $0 } Output:
|
To use metacharacters as part of a search string, their special meaning
must be disabled. This is done by preceding them with the backslash (\)
symbol. The following example prints all input lines which contain the
string "b$".
/b\$/
{ print $0 }
Special symbols recognised by awk
In addition to metacharacters, awk recognises the following C programming
language escape sequences within regular expressions and strings.
\b
backspace
\f
formfeed
\r
carriage return
\t
tab
\"
double quote
The following example prints all input lines which contain a tab character
/\t/
{ print $0 }
Consider also the use of string concatenation in pattern matching. The plus (+) symbol concatenates one or more strings in pattern matching. The following awk program (myawk16a) searches for computer types which begin with a dollar ($) symbol and are followed by an alphabetic character (a-z, A-Z), and the last character in the string is the symbol x.
#myawk16a
$1 ~ /^\$+[a-zA-Z]+x$/ { print $0 } Output:
|
awk interprets any string or variable on the right side of a ~ or !~ as a regular expression. This means the regular expression can be assigned to a variable, and the variable used later in pattern matching. An earlier awk program (myawk17) searched for input lines where field one did not contain the digits 2, 3, 4, 6 or 8.
#myawk17
# display all which do not contain 2, 3, 4, 6 or 8 in first field $1 ~ /[^23468]/ { print $0 } |
The awk program below shows how to rewrite this (myawk17) using a variable which is assigned the regular expression.
#myawk20
BEGIN { matchstr = "[^23468]" } $1 ~ matchstr { print $0 } Output:
|
Consider the following example, which searches for all lines which contain the double quote character (").
#myawk21
BEGIN { matchstr = "\"" } $1 ~ matchstr { print $0 } Output:
|
Combining Patterns
Patterns can be combined to provide more powerful and complex matching.
The following symbols are used to combine patterns.
||
logical or, either pattern can match
&&
logical and, both patterns must match
!
logical not, patterns not matching
Lets suppose we want a list of all "486" computers which have more than 250Mb of hard disk space. The following awk pattern uses the logical and to construct the necessary pattern string.
#myawk22
$1 == "486" && $5 > 250 { print $0 } Output:
|
awk Pattern Ranges
A pattern range is two patterns separated by a comma. The action is
performed for each input line between the occurrence of the first and second
pattern.
#myawk23
# demonstrate the use of pattern ranges /XT/, /Mac/ { print $0 } Output:
|
The awk program myawk23 prints out all input lines between the
first occurrence of "XT" and the next occurrence of "Mac".
awks Built In Variables
awk provides a number of internal variables which it uses to process
files. These variables are accessible by the programmer. The following
is a summary of awk's built-in variables.
ARGC
number of command-line arguments
ARGV array of command-line arguments FILENAME name of current input file FNR record number in current file FS input field separator (default= space and tab characters) NF number of fields in input line NR number of input lines read so far OFMT output format for numbers (default=%.6) OFS output field separator (default=space) ORS output line separator (default=newline) RS input line separator (default=newline) RSTART index of first character matched by match() RLENGTH length of string matched by match() SUBSEP subscript separator (default="\034") |
#myawk24
# print the first five input lines of a file, bit like head FNR == 1, FNR == 5 { print $0 } Output:
|
#myawk25
# print each input line preceded with a line number # print the heading which includes the name of the file BEGIN { print "File:", FILENAME } { print NR, ":\t", $0 } Output:
|
#myawk26
# demonstrate use of argc and argv parameters BEGIN { print "There are ",ARGC, "parameters on the command line"; print "The first argument is ", ARGV[0]; print "The second argument is ", ARGV[1] } Output:
|
#myawk27
# print out the number of fields in each input line { print "Input line", NR, "has", NF, "fields" } Output:
|
Using the BEGIN statement, it is often desirable to change both FS (the symbol used to separate fields) and RS (the symbol used to separate input lines). The following text file (awktext2) is used for the program myawk28. The test file separates each field using a dollar symbol ($), and each input line by a carat symbol (^). The program reads the file and prints out the username and password for each users record. A heading is shown only for clarity.
awktext2 data format
(username$address$password$privledge$downloadlimit$protocol^)
Joe Bloggs$767 Main Rd Tawa$smidgy$clerk$500$zmodem^Sam
Blue$1023
Kent Drive Porirua$yougessedit$normal$100$xmodem^Bobby
Williams$96
Banana Grove$mymum$sysop$3000$zmodem^
#myawk28
# a program which shows use of FS and RS, scans awktext2 BEGIN { FS = "\$"; RS = "\^" } { print "User = ", $1, " Password:", $3 } Output:
|
awks Assignment Operators
The following is a summary of awk's assignment operators.
+
add
- subtract * multiply / divide ++ increment -- decrement % modulus ^ exponential += plus equals -= minus equals *= multiply equals /= divide equals %= modulus equals ^= exponential equals |
Now some examples,
sum
= sum + 3 #
same as sum += 3
sum
= x / y
n++
# same as n = n + 1
The following awk program displays the average installed memory capacity
for an IBM type computer (XT - 486). Note the use of %f within the
printf
statement
to print out the result in floating point format. The use of .2
between the % and f symbols specify two decimal places.
#myawk29
/(XT|286|386|486)/ { computers++, ram += $2 } END { avgmem = ram / computers; printf(" The average memory per PC = %.2f", avgmem ) } Output: The average memory per PC = 4480.00 |
awks Built In Arithmetic Operators and Functions
The following is a summary of awk's built-in arithmetic operators and
functions. All operations are done in floating point format.
atan2(y,x) arctangent of y/x in radians
cos(x) cosine of x, with x in radians exp(x) exponential function of x int(x) integer part of x truncated towards 0 log(x) natural logarithm of x rand() random number between 0 and 1 sin(x) sine of x, with x in radians sqrt(x) square root of x srand(x) x is new seed for rand() |
Consider the following awk program (myawk30) which prints the square
root of an inputted value. This program also shows interactive use, by
entering the file that awk processes directly from the keyboard. If no
data file is specified (as in the example below, awk reads from the keyboard).
#myawk30, to print the square
root of a number
{ print sqrt( $1 ) } Running myawk30
Output:
|
awks Built In String Functions
The following is a summary of awk's built-in string functions. An awk
string is created by enclosing characters within quotes ("). A string can
contain C language escape sequences. The following awk string contains
the escape sequence for a new-line character.
"hello\n"
gsub(r,s) substitutes s for r globally
in current input line, returns the number of substitutions
|
The following awk program (myawk31) uses the string function gsub to replace each occurrence of 286 with the string AT.
#myawk31
{ gsub( /286/, "AT" ); print $0 } Output:
|
Part 3 or 3 Introduction to awk | home - top of the page - |
awk Control Flow Statements
awk provides a number of constructs to implement selection and iteration.
These are similar to C language constructs.
if ( expression ) statement1 else statement2
The expression can include the relational operators, the regular
expression matching operators, the logical operators and parentheses for
grouping.
expression is evaluated first, and if NON-ZERO then statement1
is executed, otherwise statement2 is executed.
In the following awk program (myawk32), each input line is scanned and field $5 is compared against the value of the awk user defined variable disksize (awk initialises it to 0). When field $5 is greater, it is assigned to disksize, and the input line is saved in the other user defined variable computer. Note the use of the braces { } to group the program statements as belonging to the if statement (same syntax as in the C language).
#myawk32
#demonstrate use of if statement, find biggest disk { if( disksize < $5 ) { disksize = $5 computer = $0 } } END { print computer } Output:
|
while ( expression ) statement
expression is evaluated, and if NON-ZERO then statement is executed, then expression is re-evaluated. This continues until expression evaluates as ZERO, at which time the while statement terminates.
#myawk33
# a while statement to print out each second field only for "286" computers BEGIN { printf("Type\tLoc\tDisk\n") } /286/ { field = 1 while( field < = NF ) { printf("%s\t", $field ) field += 2 } print "" } Output:
|
for ( expression1; expression; expression2 ) statement
The for statement provides repetition of a statement. expression1
is executed first, and is normally used to initialise variables used within
the for loop. expression is a re-evaluation which determines whether
the loop should continue. expression2 is performed at the end of
each iteration of the loop, before the re-evaluation test is performed.
1. expression1
2. expression is
evaluated. If non-zero got step 3 else exit
3. statement is executed
4. expression2 is
executed
5. goto step 2
Consider the following awk program (myawk34) which is the same as myawk33 shown earlier.
#myawk34
# a for statement to print out each second field only for "286" computers BEGIN { printf("Type\tLoc\tDisk\n") } /286/ { for( field = 1; field < = NF; field += 2) printf("%s\t", $field ) print "" } Output:
|
do statement while( expression )
The statement is executed repeatedly until the value of expression is ZERO. statement is executed at least once.
#myawk35
# print out every second field for "286" computers BEGIN { field = 1 } $1 == "286" { do { printf("%s\t", $field) field += 2 } while( field < = NF ) } Output:
|
break, continue, next, exit
The break statement causes an immediate exit from within a while
or for loop.
The continue statement causes the next iteration of a
loop.
The next statement skips to the next input line then re-starts
from the first pattern-action statement.
The exit statement causes the program to branch to the
END statement (if one exists), else it exits the program.
#myawk36
#print out computer types "286" using a next statement { while( $1 != "286" ) next; print $0 } Output:
|
Arrays in awk programs
awk provides single dimensioned arrays. Arrays need not be declared,
they are created in the same manner as awk user defined variables.
Elements can be specified as numeric or string values. Consider the following awk program (myawk37) which uses arrays to hold the number of "486" computers and the disk space totals for all computers.
#myawk37
# diskspace[] holds sum of disk space for all computers # computers[] holds number of computers of specified type $1 == "486" { computers["486"]++ } $5 > 0 { diskspace[0] += $5 } END { print "Number of 486 computers =", computers[486]; print "Total disk space = ",diskspace[0] } Output:
|
Note that the previous program (myawk37) uses TWO pattern action statements for each input line. The first pattern action statement handles the number of "486" type computers, whilst the second handles the total disk space for all computer types.
Consider the following awk program (myawk38) which uses the in statement associated with processing areas. The program .....
#myawk38
{ computers[$1]++ } END { for ( name in computers ) print "The number of ",name,"computers is",computers[name] } Output:
|
awk User Defined Functions
awk supports user defined functions. The syntax is
function
name( argument-list ) {
statements
}
The definition of a function can occur anywhere a pattern-action statement
can. argument-list is a list of variable names separated by commas.
There must be NO space between the function name and the left bracket of
the argument-list.
The return statement is used to return a value by the
function.
Consider the following awk program (myawk39) which calculates
the factorial of an inputted number.
#myawk39
function factorial( n ) { if( n < = 1 ) return 1 else return n * factorial( n - 1) } { print "the factorial of ", $1, "is ", factorial($1) } Output:
|
awk Output
The statements print and printf are used in awk programs
to generate output. awk uses two variables, OFS (output field separator)
and ORS (output record separator) to delineate fields and output
lines. These can be changed at any time.
The special characters used in printf, which follow the % symbol, are,
c single character
d decimal integer e double number, scientific notation f floating point number g use e or f, whichever is shortest o octal s string x hexadecimal % the % symbol |
The default output format is %.6g and is changed by assigning a new value to OFMT.
awk Output To Files
awks output generated by print and printf can be redirected
to a file by using the redirection symbols > (create/write) and
>
> (append). The names of files MUST be in quotes.
#myawk40
# demonstrates sending output to a file $1 == "486" { print "Type=",$1, "Location=",$3 > "comp486.dat" Output:
|
awk Output To Pipes
The output of awk programs can be piped into a UNIX command. The statement
print
" ",$1 | "sort"
causes the output of the print command to be piped to the UNIX
sort
command.
awk Input
Data Files
We have seen TWO methods to give file input to an awk program. The
first specified the filename on the command line, the other left it blank,
and awk read from the keyboard (examples were myawk30 and myawk39).
Program Files
We have used the -f parameter to specify the file containing
the awk program. awk programs can also be specified on the command-line
enclosed in single quotes, as the following example shows.
awk
'/286/ {print $0 }' awktext
Note: For MSDOS systems, a double quote must be used to enclose the
awk program when specified on the command line.
The getline function
awk provides the function getline to read input from the current
input file or from a file or pipe.
getline reads the next input line, splitting it into fields according to the settings of NF, NR and FNR. It returns 1 for success, 0 for end-of-file, and -1 on error.
The statement
getline data
reads the next input line into the user defined variable data.
No splitting of fields is done and NF is not set.
The statement
getline < "temp.dat"
reads the next input line from the file "temp.dat", field splitting
is performed, and NF is set.
The statement
getline data < "temp.dat"
reads the next input line from the file "temp.dat" into the user defined
variable data, no field splitting is done, and NF, NR and FNR are
not altered.
Consider the following example, which pipes the output of the UNIX command who into getline. Each time through the while loop, another line is read from who, and the user defined variable users is incremented. The program counts the number of users on the host system.
while ( "who" | getline )
users++
awk summary | home - top of the page - |
awk Summary
The following is a summary of the most common awk statements and features.
Command Line
awk program
filenames
awk -f
program-file filenames
awk -Fs
(sets field separator to
string s, -Ft sets separator to tab)
Patterns
BEGIN
END
/regular expression/
relational expression
pattern & &
pattern
pattern || pattern
(pattern)
!pattern
pattern, pattern
Control Flow Statements
if ( expr)
statement
[ else statement]
if ( subscript
in array) statement [ else
statement]
while ( expr)
statement
for ( expr;
expr ; expr ) statement
for ( var
in array ) statement
do statement
while ( expr)
break
continue
next
exit [ expr]
return [ expr]
Input Output
close( filename
)
close file
getline
set $0 form next input line, set NF, NR, FNR
getline <
file
set $0 from next input line of file, set NF
getline var
set var from next input line, net NR, FNR
getline var
< file
set var from next input line of file
print
print current input line
print expr-list
print expressions
print expr-list
> file print
expressions to file
printf fmt, expr-list
format and print
printf fmt, expr-list
> file format and print to file
system( cmd-line
)
execute command cmd-line, return status
In print and printf above, > > appends to a file, and the | command writes to a pipe. Similarly, command | getline pipes into getline. The function getline returns 0 on the end of a file, -1 on an error.
Functions
func name(
parameter list ) { statement }
function
name ( parameter list ) { statement }
function-name ( expr,
expr,
... )
String Functions
gsub(r,s,t)
substitutes s for r in t globally, returns number
of substitutions
index(s,t)
returns position of string t in s, 0 if not present
length(s)
returns length of s
match(s,r)
returns position in s where r occurs, 0 if not present
split(s,a,r)
splits s into array a on r, returns number of fields
sprintf(fmt, expr-list)
returns expr-list formatted according to format string specified
by fmt
sub(r,s,t)
substitutes s for first r in t, returns number of
substitutions
substr(s,p,n)
returns substring of s length n starting at position p
Arithmetic Functions
atan2(y,x)
arctangent of y/x in radians
cos(x)
cosine of x, with x in radians
exp(x)
exponential function of x
int(x)
integer part of x truncated towards 0
log(x)
natural logarithm of x
rand()
random number between 0 and 1
sin(x)
sine of x, with x in radians
sqrt(x)
square root of x
srand(x)
x is new seed for rand()
Operators (increasing precedence)
= +=
-= *= /= %= ^=
assignment
?:
conditional expression
||
logical or
& &
logical and
~ !~
regular expression match, negated match
< <
= > > = != ==
relationals
blank
string concatenation
+ -
add, subtract
* /
%
multiply, divide, modulus
+ -
!
unary plus, unary minus, logical negation
^
exponentional
++ --
increment, decrement
$
field
Regular Expressions (increasing precedence):
c
matches no-metacharacter c
\c
matches literal character c
.
matches any character except newline
^
matches beginning of line or string
$
matches end of line or string
[abc...]
character class matches any of abc...
[^abc...]
negated class matches any but abc... and newline
r1 | r2
matches either r1 or r2
r1r2
concatenation: matches r1, then r2
r+
matches one or more r's
r*
matches zero or more r's
r?
matches zeor or more r's
(r)
grouping: matches r
Built-In Variables
ARGC
number of command-line arguments
ARGV
array of command-line arguments (0..ARGC-1fR)
FILENAME
name of current input file
FNR
input line number number in current file
FS
input field separator (default blank)
NF
number of fields in input line
NR
number of input lines read so far
OFMT
output format for numbers (default=%.6g)
OFS
output field separator (default=space)
ORS
output line separator (default=newline)
RS
input line separator (default=newline)
RSTART
index of first character matched by match()
RLENGTH
length of string matched by match()
SUBSEP
subscript separator (default=\034")
Limits
Each implementation of awk imposes some limits. Below are typical limits
100 fields
2500 characters per input
line
2500 characters per output
line
1024 characters per individual
field
1024 characters per printf
string
400 characters maximum quoted
string
400 characters in character
class
15 open files
1 pipe
Converting files between MSDOS and UNIX format
MSDOS uses a CR and LF to separate each line of a file. The carriage
return character appears as a ^M symbol in the editor vi. In addition,
some MSDOS editors mark the end of a file using the CTRL-Z character.
UNIX uses a LF to separate each line of a file. There is no end
of file character.
SCO UNIX provides a mechanism for converting between MSDOS and
UNIX file formats.
dtox
converts a MSDOS file to
UNIX format (does not strip the end-of-file character).
dtox awktext > awktext.unx
It may also be necessary
to load the file into an editor and remove the end-of-file character.
xtod
converts a UNIX file to
MSDOS format.
xtod awktext.unx > awktext