|
More small fry Unix commandsCool tricks with read and wc |
Mo continues his look at "small fry" Unix commands this month with an explanation of theread
andwc
(word counter) utilities.The
read
command is usually used to accept keyboard input, but Mo shows you how it can be used to read input from a process as well. He also provides a nifty little word counting utility based on thewc
command. (1,700 words)
Mail this article to a friend |
read
The read
command is not actually a separate program in the Korn shell. It is
built into the Korn shell. Its purpose is to allow input information to be
read from standard input (usually the keyboard). In order to try out read
,
type ksh
and press Enter.
Type the following command, and then enter a single word with no spaces as in
the example below. The command read x
causes input to be read from standard input
and assigned to the variable $x, which is then echoed to the screen.
$ read x; echo $x hello hello $
read
is usually used in shell scripts to accept user input and assign it to a
variable. The following example, simpmenu, is a two-pick menu that uses read
to accept the user's input.
A menu is displayed at lines 7 through 18. At line 19 the user selection is
accepted into the variable x and then one of two possible actions is executed
at lines 20 through 23 and 25 through 28. This action is repeated until the
user enters the number 9 as a menu pick. This is controlled at line 5. If $x is not
equal (-ne
) to 9 at line 5 then the loop continues to execute.
Note the additional read
s at lines 22 and 27. These read
s seem to have no
variable named for the input. The read
command supplies a default variable
named REPLY. That is used if no variable is named with the read
command. I am
only using read
at lines 22 and 27 to give the user the opportunity to see
the last page of output before the screen is cleared.
1 # simpmenu 2 # a simple menu program 3 4 x=1 5 while [ $x -ne 9 ] 6 do 7 clear 8 echo 9 echo 10 echo "Enter your selection" 11 echo 12 echo 13 echo "1 Display directory" 14 echo "2 Display processes" 15 echo 16 echo 17 echo "9 Exit" 18 19 read x 20 if [ $x -eq 1 ] 21 then 22 ls -l|more ; echo "Press Enter" ; read 23 fi 24 25 if [ $x -eq 2 ] 26 then 27 ps -ef|more ; echo "Press Enter" ; read 28 fi 29 done
Using the default REPLY variable, the first exercise could be shortened to:
$ read; echo $REPLY hello hello $
The read
command can be used to read and fill more than one variable. Enter
the following command and then type four words separated by a space:
$ read x y z; echo $x; echo $y; echo $z one two three four one two three four $
The read
command reads in all of the words on a line and assigns them one by
one to the variables listed for the read
command. If there are more words than
there are variables, the remaining words are all assigned to the last variable. Thus $x=one, $y=two and $z=three and four.
This is true even with only one variable, as in the following listing. The $x
variable is the last variable associated with read
, and so it ends up with the
value one two three four:
$ read x; echo $x one two three four one two three four $
You can break up the list in $x by using for
, as follows:
$ read x; for name in $x; do echo $name; done one two three four one two three four $
In the multmenu listing, the user can actually enter more than one menu pick separated by spaces. At lines 20 through 34, the user selection is broken into pieces and each individual piece is processed in multiple passes.
1 # multmenu 2 # a multiple menu program 3 4 x=1 5 while [ $x -ne 9 ] 6 do 7 clear 8 echo 9 echo 10 echo "Enter your selection" 11 echo 12 echo 13 echo "1 Display directory" 14 echo "2 Display processes" 15 echo 16 echo 17 echo "9 Exit" 18 read x 19 for pick in $x 20 do 21 if [ $pick -eq 1 ] 22 then 23 ls -l|more ; echo "Press Enter" ; read 24 fi 25 if [ $pick -eq 2 ] 26 then 27 ps -ef|more ; echo "Press Enter" ; read 28 fi 29 if [ $pick -eq 9 ] 30 then 31 exit 32 fi 33 done 34 done
|
|
|
|
Reading from another process
The read
command possesses one other very powerful trick. It's possible to
start a process running that produces output, and then read that output as if
it were coming from the keyboard. This requires two steps:
read
command has to be informed that it is reading from another process
rather than from the keyboard
The listing for oldest uses this technique. The ls -tr
command lists the file
in a directory in oldest-to-newest order. The first entry in the list is
therefore the oldest. At line 4 the ls -tr
command is launched but ends with a
pipe bar and an ampersand (|&
). The ampersand indicates that the command is to
be detached and run as a background command. The pipe indicates that a
pipeline is to be created between oldest and the detached process. At line 6
read
is issued with the -p flag meaning that it is to read from the pipe
rather than from standard input. The read only goes up to the first newline
character, so it only reads the first line that is output by the ls -tr
command.
1 # oldest 2 # names the oldest file 3 4 ls -tr|& 5 6 read -p x 7 8 echo "The oldest file is" $x
The next section on wc
includes another example of using read
.
The read
command is more than simple input, and can be used for diverse tasks.
wc
The wc
command provides a count of words, lines, and characters in a document.
In the listing below, log.txt contains 154 lines, 918 words, and 4431
characters. An ls -l
listing also reveals the size of the file to be 4431
bytes in length.
$ wc log.txt 154 918 4431 log.txt $ ls -l log.txt -rw-r--r-- 1 mjb group 4431 Apr 12 14:35 log.txt
The word counter defines a word as any non-blank sequence of letters or numbers.
You may limit the output of wc
to a count of words, lines, or characters only
by using the -w,-l, and -c switches respectively. The default is
to display all three values. You may also display the results for more than one file as
the file name is displayed for each entry along with a total. The following
example displays the line counts for all files that start with log along
with a total:
$ wc -l log* 154 log.txt 5 logit.sh 159 total
The wc
utility is useful for authors. The listing for
ueditor is my own personal editor that I use to check word counts
(just kidding). It includes line numbers for explanation. The script
is invoked using the command ueditor article.txt
. At
line 3 wc
is used to count words. The terminator
|&
causes the wc
command to be started as
a background task, and opens a pipe from ueditor to the background
task in such a way that the results of the task can be read as input
by ueditor. The result is read at line 4. The wc -w
command
outputs two fields: the word count and the file name. These are read into
separate variables: $wrds and $name at line
4. The value in $wrds is tested at line 5; if it is less than
(-lt
) 2000, then words of encouragement are printed. If $wrds is
2000 or more, then the message contains some praise for your humble and hard-working
author.
1 # ueditor 2 # checks if the article has 2000 words yet 3 wc -w $1|& 4 read -p $wrds $name 5 if [ $wrds -lt 2000 ] 6 then 7 echo "Only" $wrds "words! More, more I'm still not satisfied." 8 else 9 echo "A brilliant piece!" 10 fi
|
Resources
wc
http://thyphy.physics.orst.edu/tutorial/unix/coping-with-unix/node149.html
About the author
Mo Budlong, president of King Computer Services Inc., specializes in
Unix and client/server consulting and training and currently
publishes the COBOL Just In Time Course, a crash course for
the Year 2000 problem as well as COBOL Dates and the Year
2000 which offers date solutions.
Reach Mo at mo.budlong@sunworld.com.
If you have technical problems with this magazine, contact webmaster@sunworld.com
URL: http://www.sunworld.com/swol-06-1998/swol-06-unix101.html
Last modified: