Unix 101 by Mo Budlong

More small fry Unix commands

Cool tricks with read and wc

SunWorld
June  1998
[Next story]
[Table of Contents]
[Search]
Sun's Site

Abstract
Mo continues his look at "small fry" Unix commands this month with an explanation of the read and wc (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 the wc command. (1,700 words)



Mail this
article to
a friend
Last month I started a series on Unix's smaller but no less useful commands. This month we continue the series.

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 reads at lines 22 and 27. These reads 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


Advertisements

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:

  1. The process has to be started in a special way
  2. The 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


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.

What did you think of this article?
-Very worth reading
-Worth reading
-Not worth reading
-Too long
-Just right
-Too short
-Too technical
-Just right
-Not technical enough
 
 
 
    

SunWorld
[Table of Contents]
Sun's Site
[Search]
Feedback
[Next story]
Sun's Site

[(c) Copyright  Web Publishing Inc., and IDG Communication company]

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: