Reminder - Lab 1 is out. Start working on it early..
When last we left our intrepid band, we were looking at conditionals and discussed if and elif. We have only a few more constructs to go.
The case statement
As in C or Java, there's also a case, or switch statement, whose form is as follows:
case var in pat) command command ... command ;; # Two ;;'s serve as the break pat) command command ... command ;; # Two ;;'s serve as the break pat) command command ... command ;; # Two ;;'s serve as the break esacHere's a quick example that also illustrates the use of printf for formatted output:
#!/bin/sh echo $1 case "$1" in "+") ans=`expr $2 + $3` printf "%d %s %d = %d\n" $2 $1 $3 $ans ;; "-") ans=`expr $2 - $3` printf "%d %s %d = %d\n" $2 $1 $3 $ans ;; "\*") ans=`expr $2 \* $3` # do not use * here printf "%d %s %d = %d\n" $2 $1 $3 $ans ;; "/") ans=`expr $2 / $3` printf "%d %s %d = %d\n" $2 $1 $3 $ans ;; # the default pattern is a simple * *) printf "Don't know how to do that.\n" ;; esac
The for Loop
The for loop provides a tool for processing a list of input. The input to the for loop is a list of values. Each trip through the loop it extracts one value into a variable and then enters the body of the loop. The loop stops when there are no more values left in the list to be extracted.
Let's consider the following example which prints each of the command line arguments, one at a time. We'll extract them from "$@" into $var:
for var in "$@" do echo $var doneMuch like C or Java, the shell also has a break command. As you might guess, it can be used to break out of a loop. Consider this example which stops printing command line arguments, when it gets to one whose value is "quit":
for var in "$@" do if [ "$var" = "quit" ] then break fi echo $var doneIt should be noted that a for loop without a list, e.g., for var, cycles through all the arguments typed on the command line as if you had used for var in "$@".
One last note — there's also an exit command, which takes the form exit n, where n is the exit status code that you want to return. If none is provided, the exit status of the last command to be executed prior to the exit will be returned.
The while and until Loops
The shell has a while loop similar to that seen in C or Java. It continues until the predicate is false. And, like the other loops within shell, break (and continue) can be used. Here's an example of a simple while loop that processes a variable number of command-line arguments, throwing the first one away after it's been handled:
while [ "$#" -ne 0 ] do echo "$1" shift doneThere is a similar loop, the until loop that continues until the condition is true — in other words, while the command fails. Its form is:
until command do command command done
Input/Output Redirection and Pipes
We saw the other day that we can redirect the output of a command to a file, instead of standard output (the console), via >:
cat > test-file first line second line ^D # end-of-fileSimilarly, the shell allows us to redirect input into a command from a file instead of standard input (the keyboard) by using <.
The shell also allows us to use the output of one program as input to another via a mechanism called a pipe, |, seen here
users | wc
grep
grep is the standard tool for searching a text file for a substring that matches a particular pattern. Often times this pattern is a literal, such as a word. But, on other occasions, it can be something defined using a regular expression (more on those when we get to perl). Grep assumes the input files are text files, rather than binary files. It assumes that the file is organized into one or more "lines" and reports lines that contain matches for the provided pattern. RTFM for the details of grep, but the basics are as follows:
grep [flags] [pattern] [file_list]The pattern can be any regular expression. The file_list is a space-separated list of the files to search. This list can include things defined using wildcards. The flags control the details of the way grep works. Commonly used flags include the following:
- -n: include the line number in the output
- -v: show lines that do not match instead of those that do
- -i: ignore case in doing the comparisons
cut
cut is a quick and dirty utility that comes in handy across all sorts of scripting. It selects one portion of a string. The portion can be determined by some range of bytes, some range of characters, or using some delimiter-field_list pair.
The example below prints the first three characters (-c) of each line within the file:
cat file.txt | cut -c1-3The next example uses a comma as a field delimiter and prints the third and fifth fields within each line. In this respect lines are treated as records:
cat file.txt | cut -d, -f3,5In general, the ranges can be expressed as a single number, a comma-separated list of numbers, or a range using a hyphen (-).
tr
The tr command translates certain characters within a file into certain other characters. It works with bytes within a binary file as well as characters within a text file.
tr accepts as arguments two quoted strings of equal length. It translates characters within the first quoted string into the corresponding character in the second quoted string. The example below converts a few lowercase letters into uppercase:
cat file.txt | tr "abcd" "ABCD" > outfile.txttr can also accept ranges, as seen below:
cat file.txt | tr "a-z" "A-Z" > outfile.txtThe "-d" option can be used to delete, outright, each and every instance of a particular character. The example below, for example, removes newlines ('\n') from a file:
cat file.txt | tr -d "\n" > outfile.txt
Aside: special characters can be represented by escaping their octal value. For example, '\r' can be represented as '\015' and '\n' as '\012'. man ascii if you'd like to see the character-to-number mapping.