|
Softpanorama |
May the source be with you, but remember the KISS principle ;-)
|
| Tips | Recommended Links | Humor |
Etc |
Simple AWK programs enclosed in single quotes can be typed and executed right at the Unix prompt. For example, the program
awk 'BEGIN { FS = ":" } { print $1 | "sort" }' /etc/passwd
If an input file or output file are not specified, awk will expect input from stdin or output to stdout.
AWK is very flexible about matching patterns. Patterns can be
(This last example selects lines where the two characters starting in fifth column are xx and the third field matches nasty, plus lines beginning with The, plus lines ending with mean, plus lines in which the fourth field is greater than two.)
AWK procedures are enclosed in {curly brackets}. Procedures can
(1) assign variables or arrays. For example:
BEGIN {FS = ","}
(resets the field-separator character to comma before reading input)
/string/ { count["string"]++ }
(creates array count indexing the occurrences of string)
split (substr($0,4,12),N,",")
(splits the substring at commas into arrays N[1], N[2], ...
newvar = $4*sqrt($5)
AWK operators by order of (decreasing) precedence:
Field reference: $ Increment or decrement: ++ -- Exponentiate: ^ Multiply, divide, modulus: * / % Add, subtract: + - Concatenation: (blank space) Relational: < <= > >= != == Match regular expression: ~ !~ Logical: && || C-style assignment: = += -= *= /= %= ^=
AWK arithmetic functions: exp, int, log and sqrt
AWK string functions:
index(string,substring)
returns position of first occurrence of substring in string, or 0
length[(argument)]
returns length of argument, if specified, or $0.
split(string,array[,f])
splits string by separator character f (or blanks) into array[1],
array[2], ...
substr(string,s[,l])
extracts from string starting at position number s with length
l (or the rest of string).
(2) print output. Output can be unformatted (print) or formatted (printf):
{ print $2 $1 ":" $4/$3 }
prints the first two fields in reverse order, a colon and the integer ratio of the next fields.)
{ printf "Clump %d: \t%4.1f acres \t%s. \n", $2, $4*640, $6 }
prints formatted output: %d specifies a decimal number format for the clump ID; %n.mf specifies a floating-point number format for the acreage, converted from square miles; %s specifies a string format. \t is the tab character; \n is the newline character. The input line
28 4 12 0.072 vegcov forest spearfish
would be printed as the tab-aligned output line
Clump 4: 46.1 acres forest
(3) perform flow-control (you won't need these for this class):
Do-loops:
for ( [initial expression];
[test expression];
[increment counter expression] )
{ commands }
example: for (i = 1; i <= 20; i++) does 20 iterations
If-Then-Else:
if (condition)
{ commands1 }
[ else
{ commands2 } ]
does commands1 if condition is true; commands2 (or nothing) if false; condition is any expression with relational or pattern-match operators.
Other flow-control commands:
break exits from a for loop.
continue begins next iteration of a for loop.
exit terminates remaining procedures; terminates input; executes END procedure,
if any.
The following command runs a simple awk program that searches the input file /etc/passwd for the character string `foo' (a grouping of characters is usually called a string; the term string is based on similar usage in English, such as “a string of pearls,” or “a string of cars in a train”):
awk '/foo/ { print $0 }' /etc/passwd
When lines containing `foo' are found, they are printed because `print $0' means print the current line. (Just `print' by itself means the same thing, so we could have written that instead.)
You will notice that slashes (`/') surround the string `foo' in the awk program. The slashes indicate that `foo' is the pattern to search for. This type of pattern is called a regular expression, which is covered in more detail later (see Regexp). The pattern is allowed to match parts of words. There are single quotes around the awk program so that the shell won't interpret any of it as special shell characters.
Here is what this program prints:
$ awk '/foo/ { print $0 }' BBS-list
-| fooey 555-1234 2400/1200/300 B
-| foot 555-6699 1200/300 B
-| macfoo 555-6480 1200/300 A
-| sabafoo 555-2127 1200/300 C
In an awk rule, either the pattern or the action can be omitted, but not both. If the pattern is omitted, then the action is performed for every input line. If the action is omitted, the default action is to print all lines that match the pattern.
Thus, we could leave out the action (the print statement and the
curly braces) in the previous example and the result would be the same: all lines
matching the pattern `foo' are printed. By
comparison, omitting the print statement but retaining the curly braces
makes an empty action that does nothing (i.e., no lines are printed).
Many practical awk programs are just a line or two. Following is a collection of useful, short programs to get you started. Some of these programs contain constructs that haven't been covered yet. (The description of the program will give you a good idea of what is going on, but please read the rest of the Web page to become an awk expert!) Most of the examples use a data file named data. This is just a placeholder; if you use these programs yourself, substitute your own file names for data. For future reference, note that there is often more than one way to do things in awk. At some point, you may want to look back at these examples and see if you can come up with different ways to do the same things shown here:
awk '{ if (length($0) > max) max = length($0) }
END { print max }' data
awk 'length($0) > 80' data
The sole rule has a relational expression as its pattern and it has no action—so
the default action, printing the record, is used.
expand data | awk '{ if (x < length()) x = length() }
END { print "maximum line length is " x }'
The input is processed by the expand utility to change tabs into spaces, so the widths compared are actually the right-margin columns.
awk 'NF > 0' data
This is an easy way to delete blank lines from a file (or rather, to create a new file similar to the old file but from which the blank lines have been removed).
awk 'BEGIN { for (i = 1; i <= 7; i++)
print int(101 * rand()) }'
ls -l files | awk '{ x += $5 }
END { print "total bytes: " x }'
ls -l files | awk '{ x += $5 }
END { print "total K-bytes: " (x + 1023)/1024 }'
awk -F: '{ print $1 }' /etc/passwd | sort
awk 'END { print NR }' data
awk 'NR % 2 == 0' data
If you use the expression `NR % 2 == 1' instead, the program would print the odd-numbered lines.
|
Pseudo-filesAWK knows another way to assign values to AWK variables, like in the following example:
$ awk '{ print "var is", var }' var=TEST file1This statement assigns the value "TEST" to the AWK variable "var", and then reads the files "file1" and "file2". The assignment works, because AWK interprets each file name containing an equal sign ("=") as an assignment.
This example is very portable (even oawk understands this syntax), and easy to use. So why don't we use this syntax exclusively?
This syntax has two drawbacks: the variable assignment are interpreted by AWK the moment the file would have been read. At this time the assignment takes place. Since the
BEGINaction is performed before the first file is read, the variable is not available in theBEGINaction.The second problem is, that the order of the variable assignments and of the files are important. In the following example
$ awk '{ print "var is", var }' file1 var=TEST file2the variable var is not defined during the read of file1, but during the reading of file2. This may cause bugs that are hard to track down.
EXAMPLES # is the comment character for awk. 'field' means 'column'
# Print first two fields in opposite order:
awk '{ print $2, $1 }' file
# Print lines longer than 72 characters:
awk 'length > 72' file
# Print length of string in 2nd column
awk '{print length($2)}' file
# Add up first column, print sum and average:
{ s += $1 }
END { print "sum is", s, " average is", s/NR }
# Print fields in reverse order:
awk '{ for (i = NF; i > 0; --i) print $i }' file
# Print the last line
{line = $0}
END {print line}
# Print the total number of lines that contain the word Pat
/Pat/ {nlines = nlines + 1}
END {print nlines}
# Print all lines between start/stop pairs:
awk '/start/, /stop/' file
# Print all lines whose first field is different from previous one:
awk '$1 != prev { print; prev = $1 }' file
# Print column 3 if column 1 > column 2:
awk '$1 > $2 {print $3}' file
# Print line if column 3 > column 2:
awk '$3 > $2' file
# Count number of lines where col 3 > col 1
awk '$3 > $1 {print i + "1"; i++}' file
# Print sequence number and then column 1 of file:
awk '{print NR, $1}' file
# Print every line after erasing the 2nd field
awk '{$2 = ""; print}' file
# Print hi 28 times
yes | head -28 | awk '{ print "hi" }'
# Print hi.0010 to hi.0099 (NOTE IRAF USERS!)
yes | head -90 | awk '{printf("hi00%2.0f \n", NR+9)}'
# Replace every field by its absolute value
{ for (i = 1; i <= NF; i=i+1) if ($i < 0) $i = -$i print}
# If you have another character that delimits fields, use the -F option
# For example, to print out the phone number for Jones in the following file,
# 000902|Beavis|Theodore|333-242-2222|149092
# 000901|Jones|Bill|532-382-0342|234023
# ...
# type
awk -F"|" '$2=="Jones"{print $4}' filename
# Some looping for printouts
BEGIN{
for (i=875;i>833;i--){
printf "lprm -Plw %d\n", i
} exit
}
Formatted printouts are of the form printf( "format\n", value1, value2, ... valueN)
e.g. printf("howdy %-8s What it is bro. %.2f\n", $1, $2*$3)
%s = string
%-8s = 8 character string left justified
%.2f = number with 2 places after .
%6.2f = field 6 chars with 2 chars after .
\n is newline
\t is a tab
# Print frequency histogram of column of numbers
$2 <= 0.1 {na=na+1}
($2 > 0.1) && ($2 <= 0.2) {nb = nb+1}
($2 > 0.2) && ($2 <= 0.3) {nc = nc+1}
($2 > 0.3) && ($2 <= 0.4) {nd = nd+1}
($2 > 0.4) && ($2 <= 0.5) {ne = ne+1}
($2 > 0.5) && ($2 <= 0.6) {nf = nf+1}
($2 > 0.6) && ($2 <= 0.7) {ng = ng+1}
($2 > 0.7) && ($2 <= 0.8) {nh = nh+1}
($2 > 0.8) && ($2 <= 0.9) {ni = ni+1}
($2 > 0.9) {nj = nj+1}
END {print na, nb, nc, nd, ne, nf, ng, nh, ni, nj, NR}
# Find maximum and minimum values present in column 1
NR == 1 {m=$1 ; p=$1}
$1 >= m {m = $1}
$1 <= p {p = $1}
END { print "Max = " m, " Min = " p }
# Example of defining variables, multiple commands on one line
NR == 1 {prev=$4; preva = $1; prevb = $2; n=0; sum=0}
$4 != prev {print preva, prevb, prev, sum/n; n=0; sum=0; prev = $4; preva = $1; prevb = $2}
$4 == prev {n++; sum=sum+$5/$6}
END {print preva, prevb, prev, sum/n}
# Example of using substrings
# substr($2,9,7) picks out characters 9 thru 15 of column 2
{print "imarith", substr($2,1,7) " - " $3, "out."substr($2,5,3)}
{print "imarith", substr($2,9,7) " - " $3, "out."substr($2,13,3)}
{print "imarith", substr($2,17,7) " - " $3, "out."substr($2,21,3)}
{print "imarith", substr($2,25,7) " - " $3, "out."substr($2,29,3)}
For example, suppose I want to turn a document with single-spacing into a document with double-spacing. I could easily do that with the following Awk program:
awk '{print ; print ""}' infile > outfileNotice how single-quotes (' ') are used to allow using double-quotes (" ") within the Awk expression. This "hides" special characters from the shell you are using. You could also do this as follows:-- but the single-quote method is simpler. awk "{print ; print \"\"}" infile > outfileThis program does what it supposed to, but it also doubles every blank line in the input file, which leaves a lot of empty space in the output. That's easy to fix, just tell Awk to print an extra blank line if the current line is not blank:
awk '{print ; if (NF != 0) print ""}' infile > outfile* One of the problems with Awk is that it is ingenious enough to make a user want to tinker with it, and use it for tasks for which it isn't really appropriate. For example, you could use Awk to count the number of lines in a file:-- but this is dumb, because the "wc (word count)" utility gives the same answer with less bother. "Use the right tool for the job." awk 'END {print NR}' infileAwk is the right tool for slightly more complicated tasks. Once I had a file containing an email distribution list. The email addresses of various different groups were placed on consecutive lines in the file, with the different groups separated by blank lines. If I wanted to quickly and reliably determine how many people were on the distribution list, I couldn't use "wc", since, it counts blank lines, but Awk handled it easily:
awk 'NF != 0 {++count} END {print count}' list* Another problem I ran into was determining the average size of a number of files. I was creating a set of bitmaps with a scanner and storing them on a floppy disk. The disk started getting full and I was curious to know just how many more bitmaps I could store on the disk.I could obtain the file sizes in bytes using "wc -c" or the "list" utility ("ls -l" or "ll"). A few tests showed that "ll" was faster. Since "ll" lists the file size in the fifth field, all I had to do was sum up the fifth field and divide by NR. There was one slight problem, however: the first line of the output of "ll" listed the total number of sectors used, and had to be skipped.
No problem. I simply entered:
ll | awk 'NR!=1 {s+=$5} END {print "Average: " s/(NR-1)}'This gave me the average as about 40 KB per file.* Awk is useful for performing simple iterative computations for which a more sophisticated language like C might prove overkill. Consider the Fibonacci sequence:
1 1 2 3 5 8 13 21 34 ...Each element in the sequence is constructed by adding the two previous elements together, with the first two elements defined as both "1". It's a discrete formula for exponential growth. It is very easy to use Awk to generate this sequence:This generates the following output data: awk 'BEGIN {a=1;b=1; while(++x<=10){print a; t=a;a=a+b;b=t}; exit}' 1 2 3 5 8 13 21 34 55 89
A colleague of mine used AWK to extract the first column from a file with the command:
awk ' '{print $1}' file
Easy, isn't it? This simple task does not need complex programming in C. One line of AWK does it. Once we have learned the lesson on how to extract a column we can do things such as renaming files (append .new to "files_list"):
ls files_list | awk '{print "mv "$1" "$1".new"}' | sh... and more:
- Renaming within the name:
ls -1 *old* | awk '{print "mv "$1" "$1}' | sed s/old/new/2 | sh
(although in some cases it will fail, as in file_old_and_old)- Remove only files:
ls -l * | grep -v drwx | awk '{print "rm "$9}' | sh
or with awk alone:
ls -l|awk '$1!~/^drwx/{print $9}'|xargs rm
Be careful when trying this out in your home directory. We remove files!- Remove only directories
ls -l | grep '^d' | awk '{print "rm -r "$9}' | sh
or
ls -p | grep /$ | wk '{print "rm -r "$1}'
or with awk alone:
ls -l|awk '$1~/^d.*x/{print $9}'|xargs rm -r
Be careful when trying this out in your home directory. We remove things!- Killing processes by name (in this example we kill the process called netscape):
kill `ps auxww | grep netscape | egrep -v grep | awk '{print $2}'`
or with awk alone:
ps auxww | awk '$0~/netscape/&&$0!~/awk/{print $2}' |xargs kill
It has to be adjusted to fit the ps command on whatever unix system you are on. Basically it is: "If the process is called netscape and it is not called 'grep netscape' (or awk) then print the pid"
Useful
awkprograms are often short, just a line or two. Here is a collection of useful, short programs to get you started. Some of these programs contain constructs that haven't been covered yet. The description of the program will give you a good idea of what is going on, but please read the rest of the manual to become anawkexpert!
awk '{ if (NF > max) max = NF }END { print max }'- This program prints the maximum number of fields on any input line.
awk 'length($0) > 80'- This program prints every line longer than 80 characters. The sole rule has a relational expression as its pattern, and has no action (so the default action, printing the record, is used).
awk 'NF > 0'- This program prints every line that has at least one field. This is an easy way to delete blank lines from a file (or rather, to create a new file similar to the old file but from which the blank lines have been deleted).
awk '{ if (NF > 0) print }'- This program also prints every line that has at least one field. Here we allow the rule to match every line, then decide in the action whether to print.
awk 'BEGIN { for (i = 1; i <= 7; i++)print int(101 * rand()) }'- This program prints 7 random numbers from 0 to 100, inclusive.
ls -l files | awk '{ x += $4 } ; END { print "total bytes: " x }'- This program prints the total number of bytes used by files.
expand file | awk '{ if (x < length()) x = length() }END { print "maximum line length is " x }'- This program prints the maximum line length of file. The input is piped through the
expandprogram to change tabs into spaces, so the widths compared are actually the right-margin columns.awk 'BEGIN { FS = ":" }{ print $1 | "sort" }' /etc/passwd- This program prints a sorted list of the login names of all users.
awk '{ nlines++ }END { print nlines }'- This programs counts lines in a file.
awk 'END { print NR }'- This program also counts lines in a file, but lets
awkdo the work.awk '{ print NR, $0 }'- This program adds line numbers to all its input files, similar to `cat -n'.
HANDY ONE-LINERS FOR AWK 22 July 2003
compiled by Eric Pement <pemente@northpark.edu> version 0.22
Latest version of this file is usually at:
http://www.student.northpark.edu/pemente/awk/awk1line.txt
USAGE:
Unix: awk '/pattern/ {print "$1"}' # standard Unix shells
DOS/Win: awk '/pattern/ {print "$1"}' # okay for DJGPP compiled
awk "/pattern/ {print \"$1\"}" # required for Mingw32
Most of my experience comes from version of GNU awk (gawk) compiled for
Win32. Note in particular that DJGPP compilations permit the awk script
to follow Unix quoting syntax '/like/ {"this"}'. However, the user must
know that single quotes under DOS/Windows do not protect the redirection
arrows (<, >) nor do they protect pipes (|). Both are special symbols
for the DOS/CMD command shell and their special meaning is ignored only
if they are placed within "double quotes." Likewise, DOS/Win users must
remember that the percent sign (%) is used to mark DOS/Win environment
variables, so it must be doubled (%%) to yield a single percent sign
visible to awk.
If I am sure that a script will NOT need to be quoted in Unix, DOS, or
CMD, then I normally omit the quote marks. If an example is peculiar to
GNU awk, the command 'gawk' will be used. Please notify me if you find
errors or new commands to add to this list (total length under 65
characters). I usually try to put the shortest script first.
FILE SPACING:
# double space a file
awk '1;{print ""}'
awk 'BEGIN{ORS="\n\n"};1'
# double space a file which already has blank lines in it. Output file
# should contain no more than one blank line between lines of text.
# NOTE: On Unix systems, DOS lines which have only CRLF (\r\n) are
# often treated as non-blank, and thus 'NF' alone will return TRUE.
awk 'NF{print $0 "\n"}'
# triple space a file
awk '1;{print "\n"}'
NUMBERING AND CALCULATIONS:
# precede each line by its line number FOR THAT FILE (left alignment).
# Using a tab (\t) instead of space will preserve margins.
awk '{print FNR "\t" $0}' files*
# precede each line by its line number FOR ALL FILES TOGETHER, with tab.
awk '{print NR "\t" $0}' files*
# number each line of a file (number on left, right-aligned)
# Double the percent signs if typing from the DOS command prompt.
awk '{printf("%5d : %s\n", NR,$0)}'
# number each line of file, but only print numbers if line is not blank
# Remember caveats about Unix treatment of \r (mentioned above)
awk 'NF{$0=++a " :" $0};{print}'
awk '{print (NF? ++a " :" :"") $0}'
# count lines (emulates "wc -l")
awk 'END{print NR}'
# print the sums of the fields of every line
awk '{s=0; for (i=1; i<=NF; i++) s=s+$i; print s}'
# add all fields in all lines and print the sum
awk '{for (i=1; i<=NF; i++) s=s+$i}; END{print s}'
# print every line after replacing each field with its absolute value
awk '{for (i=1; i<=NF; i++) if ($i < 0) $i = -$i; print }'
awk '{for (i=1; i<=NF; i++) $i = ($i < 0) ? -$i : $i; print }'
# print the total number of fields ("words") in all lines
awk '{ total = total + NF }; END {print total}' file
# print the total number of lines that contain "Beth"
awk '/Beth/{n++}; END {print n+0}' file
# print the largest first field and the line that contains it
# Intended for finding the longest string in field #1
awk '$1 > max {max=$1; maxline=$0}; END{ print max, maxline}'
# print the number of fields in each line, followed by the line
awk '{ print NF ":" $0 } '
# print the last field of each line
awk '{ print $NF }'
# print the last field of the last line
awk '{ field = $NF }; END{ print field }'
# print every line with more than 4 fields
awk 'NF > 4'
# print every line where the value of the last field is > 4
awk '$NF > 4'
TEXT CONVERSION AND SUBSTITUTION:
# IN UNIX ENVIRONMENT: convert DOS newlines (CR/LF) to Unix format
awk '{sub(/\r$/,"");print}' # assumes EACH line ends with Ctrl-M
# IN UNIX ENVIRONMENT: convert Unix newlines (LF) to DOS format
awk '{sub(/$/,"\r");print}
# IN DOS ENVIRONMENT: convert Unix newlines (LF) to DOS format
awk 1
# IN DOS ENVIRONMENT: convert DOS newlines (CR/LF) to Unix format
# Cannot be done with DOS versions of awk, other than gawk:
gawk -v BINMODE="w" '1' infile >outfile
# Use "tr" instead.
tr -d \r <infile >outfile # GNU tr version 1.22 or higher
# delete leading whitespace (spaces, tabs) from front of each line
# aligns all text flush left
awk '{sub(/^[ \t]+/, ""); print}'
# delete trailing whitespace (spaces, tabs) from end of each line
awk '{sub(/[ \t]+$/, "");print}'
# delete BOTH leading and trailing whitespace from each line
awk '{gsub(/^[ \t]+|[ \t]+$/,"");print}'
awk '{$1=$1;print}' # also removes extra space between fields
# insert 5 blank spaces at beginning of each line (make page offset)
awk '{sub(/^/, " ");print}'
# align all text flush right on a 79-column width
awk '{printf "%79s\n", $0}' file*
# center all text on a 79-character width
awk '{l=length();s=int((79-l)/2); printf "%"(s+l)"s\n",$0}' file*
# substitute (find and replace) "foo" with "bar" on each line
awk '{sub(/foo/,"bar");print}' # replaces only 1st instance
gawk '{$0=gensub(/foo/,"bar",4);print}' # replaces only 4th instance
awk '{gsub(/foo/,"bar");print}' # replaces ALL instances in a line
# substitute "foo" with "bar" ONLY for lines which contain "baz"
awk '/baz/{gsub(/foo/, "bar")};{print}'
# substitute "foo" with "bar" EXCEPT for lines which contain "baz"
awk '!/baz/{gsub(/foo/, "bar")};{print}'
# change "scarlet" or "ruby" or "puce" to "red"
awk '{gsub(/scarlet|ruby|puce/, "red"); print}'
# reverse order of lines (emulates "tac")
awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' file*
# if a line ends with a backslash, append the next line to it
# (fails if there are multiple lines ending with backslash...)
awk '/\\$/ {sub(/\\$/,""); getline t; print $0 t; next}; 1' file*
# print and sort the login names of all users
awk -F ":" '{ print $1 | "sort" }' /etc/passwd
# print the first 2 fields, in opposite order, of every line
awk '{print $2, $1}' file
# switch the first 2 fields of every line
awk '{temp = $1; $1 = $2; $2 = temp}' file
# print every line, deleting the second field of that line
awk '{ $2 = ""; print }'
# print in reverse order the fields of every line
awk '{for (i=NF; i>0; i--) printf("%s ",i);printf ("\n")}' file
# remove duplicate, consecutive lines (emulates "uniq")
awk 'a !~ $0; {a=$0}'
# remove duplicate, nonconsecutive lines
awk '! a[$0]++' # most concise script
awk '!($0 in a) {a[$0];print}' # most efficient script
# concatenate every 5 lines of input, using a comma separator
# between fields
awk 'ORS=%NR%5?",":"\n"' file
SELECTIVE PRINTING OF CERTAIN LINES:
# print first 10 lines of file (emulates behavior of "head")
awk 'NR < 11'
# print first line of file (emulates "head -1")
awk 'NR>1{exit};1'
# print the last 2 lines of a file (emulates "tail -2")
awk '{y=x "\n" $0; x=$0};END{print y}'
# print the last line of a file (emulates "tail -1")
awk 'END{print}'
# print only lines which match regular expression (emulates "grep")
awk '/regex/'
# print only lines which do NOT match regex (emulates "grep -v")
awk '!/regex/'
# print the line immediately before a regex, but not the line
# containing the regex
awk '/regex/{print x};{x=$0}'
awk '/regex/{print (x=="" ? "match on line 1" : x)};{x=$0}'
# print the line immediately after a regex, but not the line
# containing the regex
awk '/regex/{getline;print}'
# grep for AAA and BBB and CCC (in any order)
awk '/AAA/; /BBB/; /CCC/'
# grep for AAA and BBB and CCC (in that order)
awk '/AAA.*BBB.*CCC/'
# print only lines of 65 characters or longer
awk 'length > 64'
# print only lines of less than 65 characters
awk 'length < 64'
# print section of file from regular expression to end of file
awk '/regex/,0'
awk '/regex/,EOF'
# print section of file based on line numbers (lines 8-12, inclusive)
awk 'NR==8,NR==12'
# print line number 52
awk 'NR==52'
awk 'NR==52 {print;exit}' # more efficient on large files
# print section of file between two regular expressions (inclusive)
awk '/Iowa/,/Montana/' # case sensitive
SELECTIVE DELETION OF CERTAIN LINES:
# delete ALL blank lines from a file (same as "grep '.' ")
awk NF
awk '/./'
CREDITS AND THANKS:
Special thanks to Peter S. Tillier for helping me with the first release
of this FAQ file.
For additional syntax instructions, including the way to apply editing
commands from a disk file instead of the command line, consult:
"sed & awk, 2nd Edition," by Dale Dougherty and Arnold Robbins
O'Reilly, 1997
"UNIX Text Processing," by Dale Dougherty and Tim O'Reilly
Hayden Books, 1987
"Effective awk Programming, 3rd Edition." by Arnold Robbins
O'Reilly, 2001
To fully exploit the power of awk, one must understand "regular
expressions." For detailed discussion of regular expressions, see
"Mastering Regular Expressions, 2d edition" by Jeffrey Friedl
(O'Reilly, 2002).
The manual ("man") pages on Unix systems may be helpful (try "man awk",
"man nawk", "man regexp", or the section on regular expressions in "man
ed"), but man pages are notoriously difficult. They are not written to
teach awk use or regexps to first-time users, but as a reference text
for those already acquainted with these tools.
USE OF '\t' IN awk SCRIPTS: For clarity in documentation, we have used
the expression '\t' to indicate a tab character (0x09) in the scripts.
All versions of awk, even the UNIX System 7 version should recognize
the '\t' abbreviation.
#---end of file---
Although awk can be used to write programs of some complexity, many useful programs are not complicated. Here is a collection of short programs that you might find handy and/or instructive:Source: The AWK Programming Language
- Print the total numnber of input lines:
END { print NR }- Print the tenth input line:
NR == 10- Print the last field of every input line:
{ print $NF }- Print the last field of the last input line:
{ field = $NF} END { print field }- Print every input line with more than 4 fields:
NF > 4- Print every input line in which the last field is more than 4:
$NF > 4- Print the total number of fields in all input lines:
{ nf = nf + NF } END { print nf }- Print the total number of lines that contain Beth:
/Beth/ { nlines = nlines + 1 } END { print nlines }- Print the largest first fields and the line that contains it ( assumes some $1 is positive):
$1 > max { max = $1 ; maxlines = $0 } END { print max, maxline)- Print every line that has at least one field:
NF > 0- Pritn every line longer than 80 characters:
length($0) > 80- Print the numer of fields in every line, followed by the line itself:
{ print NF, $0 }- Print the first two fields, in opposite order, of every line:
{ print $2, $1 }- Exchange the first two fields of every line and then print the line:
{ temp = $1 ; $1 = $2 ; $2 = temp ; print }- Print every line witg rge first field replaced by the line number:
{ $1 = NR ; print }- Print every line after erasing the second field:
{ $2 = ""; print }- Print in reverse order the fields of every line:
{ for (i=NF ; i>0 ; i=i-1) printf( "%s ", $1) printf("\n") }- Print the sums of the fields of every line:
{ sum = 0 for ( i=1 ; i<=NF ; i=i+1) sum = sum + $i print sum }- Ad up all fields in all lines and print the sum:
{ for ( i=1 ; i<=NF ; i=i+1 ) sum = sum + $i} END { print sum }- Print every line after replacing each field by its absolute value:
{ for (i=1 ; i<=NF ; i=i+1) if ($i<0) $i=-$i print }
Useful "One-liners"
*******************
Useful `awk' programs are often short, just a line or two. Here is a
collection of useful, short programs to get you started. Some of these
programs contain constructs that haven't been covered yet. The
description of the program will give you a good idea of what is going
on, but please read the rest of the manual to become an `awk' expert!
Since you are reading this in Info, each line of the example code is
enclosed in quotes, to represent text that you would type literally.
The examples themselves represent shell commands that use single quotes
to keep the shell from interpreting the contents of the program. When
reading the examples, focus on the text between the open and close
quotes.
`awk '{ if (NF > max) max = NF }'
` END { print max }''
This program prints the maximum number of fields on any input line.
`awk 'length($0) > 80''
This program prints every line longer than 80 characters. The sole
rule has a relational expression as its pattern, and has no action
(so the default action, printing the record, is used).
`awk 'NF > 0''
This program prints every line that has at least one field. This
is an easy way to delete blank lines from a file (or rather, to
create a new file similar to the old file but from which the blank
lines have been deleted).
`awk '{ if (NF > 0) print }''
This program also prints every line that has at least one field.
Here we allow the rule to match every line, then decide in the
action whether to print.
`awk 'BEGIN { for (i = 1; i <= 7; i++)'
` print int(101 * rand()) }''
This program prints 7 random numbers from 0 to 100, inclusive.
`ls -l FILES | awk '{ x += $4 } ; END { print "total bytes: " x }''
This program prints the total number of bytes used by FILES.
`expand FILE | awk '{ if (x < length()) x = length() }'
` END { print "maximum line length is " x }''
This program prints the maximum line length of FILE. The input is
piped through the `expand' program to change tabs into spaces, so
the widths compared are actually the right-margin columns.
`awk 'BEGIN { FS = ":" }'
` { print $1 | "sort" }' /etc/passwd'
This program prints a sorted list of the login names of all users.
`awk '{ nlines++ }'
` END { print nlines }''
This programs counts lines in a file.
`awk 'END { print NR }''
This program also counts lines in a file, but lets `awk' do the
work.
`awk '{ print NR, $0 }''
This program adds line numbers to all its input files, similar to
`cat -n'.
Useful
awkprograms are often short, just a line or two. Here is a collection of useful, short programs to get you started. Some of these programs contain constructs that haven't been covered yet. The description of the program will give you a good idea of what is going on, but please read the rest of the manual to become anawkexpert!
awk '{ if (NF > max) max = NF }END { print max }'- This program prints the maximum number of fields on any input line.
awk 'length($0) > 80'- This program prints every line longer than 80 characters. The sole rule has a relational expression as its pattern, and has no action (so the default action, printing the record, is used).
awk 'NF > 0'- This program prints every line that has at least one field. This is an easy way to delete blank lines from a file (or rather, to create a new file similar to the old file but from which the blank lines have been deleted).
awk '{ if (NF > 0) print }'- This program also prints every line that has at least one field. Here we allow the rule to match every line, then decide in the action whether to print.
awk 'BEGIN { for (i = 1; i <= 7; i++)print int(101 * rand()) }'- This program prints 7 random numbers from 0 to 100, inclusive.
ls -l files | awk '{ x += $4 } ; END { print "total bytes: " x }'- This program prints the total number of bytes used by files.
expand file | awk '{ if (x < length()) x = length() }END { print "maximum line length is " x }'- This program prints the maximum line length of file. The input is piped through the
expandprogram to change tabs into spaces, so the widths compared are actually the right-margin columns.awk 'BEGIN { FS = ":" }{ print $1 | "sort" }' /etc/passwd- This program prints a sorted list of the login names of all users.
awk '{ nlines++ }END { print nlines }'- This programs counts lines in a file.
awk 'END { print NR }'- This program also counts lines in a file, but lets
awkdo the work.awk '{ print NR, $0 }'- This program adds line numbers to all its input files, similar to `cat -n'
Copyright © 1996-2007 by Dr. Nikolai Bezroukov. www.softpanorama.org was created as a service to the UN Sustainable Development Networking Programme (SDNP) in the author free time. Submit comments This document is an industrial compilation designed and created exclusively for educational use and is placed under the copyright of the Open Content License(OPL). Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.
Standard disclaimer: The statements, views and opinions presented on this web page are those of the author and are not endorsed by, nor do they necessarily reflect, the opinions of the author present and former employers, SDNP or any other organization the author may be associated with. We do not warrant the correctness of the information provided or its fitness for any purpose.
Last modified: March 15, 2008