COMS 3157 Advanced Programming

Recitation 6: Pipes and Redirection in the Shell

In this recitation, we will look at how to apply redirection and pipes to various tasks when working in the shell. Though you are not expected to memorize each of these commands, what they do, and the flags they support, this exercise will hopefully inspire you to use some of these commands and their features in your daily workflows, in this course and beyond.

Before getting started, make sure you have a copy of our Wordle solutions. You can obtain those solutions following our Lab Workflow guide, or just by cloning a fresh copy of the skeleton repo (which now contains the solutions) somewhere outside of your ~/cs3157/ directory:

git clone ~j-hui/cs3157-pub/lab1
cd lab1/solutions/part2

6.1 Revisiting the basics

For the first part of this recitation, we will look at several commands you should have seen and used before by this point. To answer these questions, read each command’s man pages, and try running them yourself.

6.2 Teaching an old cat new tricks

We normally just use cat to display the contents of text files, but can do far more that that, despite being an extremely simple shell utility.

6.3 Word count

wc is a handy utility used to count the number of lines, words, or bytes in files. Like cat, wc normally takes a list of file names as arguments, but treats the - file name specially.

wc normally reports all of those counts, but we can ask it to only report the number of lines by passing it the -l flag. For example, we can verify that there are indeed 1000 words in the common1000 words list:

$ wc -l < words/common1000
1000

6.4 Who needs games when you’ve got grep?

grep is another staple of UNIX shell utilities, and is used to search through and filter lines of text. Like cat and wc, it can be used to search through a list of files, or through input coming from stdin.

For example, to search for any words that contain the letter m in our short list of words:

grep m words/short-list

Or to search for any words that contain the substring gre in common1000:

grep gre common1000

grep has a lot of features, which you can read about using man grep. One of the more useful flags is the -r “recursive” flag, which asks grep to search every file in every subdirectory:

grep -r hello

Another useful flag is -v, which inverts the grep query and only prints out lines that do not contain your search term.

6.5 Real Wordle problems

If you haven’t already, compile the Wordle solutions by running make.

In shell syntax, you can expand the output of one command into another, using $(). For example, if you run:

wc -l $(echo game.c words.c)

echo game.c words.c outputs game.c words.c, so the above command will effectively evaluate:

wc -l game.c words.c

The run-tests.sh script uses this to automatically run each test case. For example, for the test case named hello1, it runs:

./wordle $(cat tests/hello1.test) < tests/hello1.in > test-output/hello1.out

The $(cat tests/hello1.test) expands to the arguments needed for the hello1 test case, while < tests/hello1.in redirects test input to ./wordle’s stdin.

There’s also a system-wide word list installed in /usr/share/dict/words, that (supposedly) contains every word in the English dictionary, with each word on its own line.

Solutions

Note that the answers to some of these questions don’t actually matter (some of don’t even have a fixed answer). What’s more important are the commands you need to run to obtain those answers, and the thought process that goes into figuring out what command to run. What’s most important is understanding that thought process, and how you incorporate into your command-line workflow.