Basic - Regex Fall 2026
Submission Instructions
This homework will be submitted as a repository on the EECS GitLab
server. The repository you submit will be a private Project with
the name/path eecs201-basic-regex with akamil added as a Reporter. The branch main
will be the one that is checked.
To finish the submission process and get your submission score, you will need to run the autograder. You will need to SSH into the course server (see Basic - Intro):
local$ ssh uniqname@peritia.eecs.umich.edu
(the local$
referring to a shell prompt on your system)
and then run eecs201-test:
peritia$ eecs201-test basic-regex
(the peritia$
referring to a shell prompt on the server)
The repository should have the following directory structure, starting from the repository’s root:
/
|-- report.txt
|-- grep/
| |-- cap-vow.sh
| |-- ing.sh
| |-- n-letter.sh
| |-- same-lower-vowel.sh
|
|-- sed/
|-- c89ify.sh
Preface
In this assignment you’ll be provided yet another zipped archive containing some starter empty files and scripts. Use your preferred tool to retrieve this file and extract it (see Basic - Git 1 if you need a review).
https://www.eecs.umich.edu/courses/eecs201/fa2026/files/assignments/basic-regex.tar.gz
Initialize a Git repository in the extracted
basic-regex directory
as per the submission instructions.
Regex fun
As mentioned in lecture,
grep is a utility
that finds patterns in files. These patterns are by default POSIX basic
regular expressions;
egrep or
grep with the
-E flag will
interpret patterns as POSIX extended regular expressions.
For this question we’ll be looking at an American English dictionary.
This file is located under
/usr/share/dict/american-english.
If you don’t have it, on Ubuntu (and WSL Ubuntu) you can get it via the
wamerican package and
on Arch you can get it via the
words package. If you
are on macOS, you probably already have a dictionary file
/usr/share/dict/words
which you can use for the following examples and as input for this part
of the assginment.
/usr/share/dict/words
is a standard file that contains a list of dictionary words; it’s
probably symlinked to an appropriate dictionary file.
If you want to, you could also grab the copy on the course server.
$ scp youruniqname@peritia.eecs.umich.edu:/usr/share/dict/american-english .
scp is a utility that
can copy files between one computer and another (when the remote
computer is addressable by the local computer). In particular, this one
will copy the file on the server to the current directory. You’ll have
to change the invocation of the scripts to refer to this particular file
path. Do note that these scripts can work with any file that has a word
on each line in it: you can take advantage of this to do your own simple
testing, just replace the dictionary path argument with the path to your
dictionary file.
-
Feel free to use
/usr/share/dict/american-englishor/usr/share/dict/words. You can also put together your own dictionary files for testing! -
cdinto thegrepdirectory. -
Run
$ grep "world" /usr/share/dict/american-english. This finds and prints out words in the dictionary that contain “world” anywhere in the word.(If your dictionary file is somewhere else, use that file path instead e.g.
$ grep "world" american-englishif it’s in your current directory.) -
Run
$ grep "[A-Z]" /usr/share/dict/american-english. This finds and prints out words in the dictionary that start with a capital letter.(If your dictionary file is somewhere else, use that file path instead e.g.
$ grep "[A-Z]" american-englishif it’s in your current directory.)
Now onto the question proper:
-
Implement the functionality described in each of the Bash scripts. You may only use one
grepcommand in each script. Each script takes in the path to some dictionary file as an argument. This can be the American English dictionary or your own test dictionary (a file with a word on each line). Feel free to use ERE via the-Eflag forgrep. -
Remember that the path to the dictionary is an argument for the script, and that you should pass that argument to
grep! Do not hardcode what dictionarygrepuses! This is determined at runtime by the person (or autograder) running the script! -
Stage and commit your changes.
Searching and replacing text with sed
sed is a utility that
is able to perform pattern searches and replacements. By default
sed will use POSIX
BRE unless a parameter is specified to use ERE.
-
cdinto theseddirectory. -
Run
$ sed -e 's/hello/world/' <<<'hello user hello'. Whatseddid is replace the first instance of “hello” with “world” of each line of input.sis the command to “substitute” texts, with the following charactering serving as a delimiter (sed -e 's@hello@world@'would also work, with it using ’@’ as a delimiter instead of ’/’). Thescommand is of the formats/pattern/replacement/flags. -
Run
$ sed -e 's/hello/world/g' <<<'hello user hello'. Note that both “hello”s were replaced. Thegat the end of thesedscommand is a flag that says to replace all matches, not only the first. -
Run
$ grep -E '(hello) (.*) \1' <<<'hello user hello'.Try it again with a here string of
'hello user goodbye'. Note how we can re-use part of a pattern using parentheses and a backreference. -
Run
$ sed -E -e 's/hello (.*)/goodbye \1/g' <<<'hello world'Note the-Eflag: this putssedinto ERE mode. Note the use of backreferences in the replacement field.
Now onto the question proper. Take a look at
saxpy.c. Note how it
uses // for comments.
-
Run
$ gcc -pedantic -Werror -std=c99 saxpy.c. This will compile the C program following the C99 standard. It should compile successfully. Feel free to run thea.outbinary that is produced. -
Now run
$ gcc -pedantic -Werror -std=c89 saxpy.c. This will compile the C program following the C89 (“ANSI C”) standard. It should fail to compile. That is because C++ actually introduced the use of//for single single line comments, support for which the C99 standard added to the C language. -
In the provided
c89ify.shfile, implement the script as described by its usage printout. What this script is supposed to do is take in a list of C files as arguments and then for each C file, replace the// commentcomments with/* comment */style comments and put a “fixed” version of the file into a new file that tacks on.c89before the.cextension. For example,./c89ify.sh saxpy.c daxpy.cwill produce fixed versions insaxpy.c89.canddaxpy.c89.cand leavingsaxpy.canddaxpy.cas they originally were. -
Some notes
-
Remember you can test out
sedat the command line to quickly iterate on yourscommand: by defaultsedis non-destructive and simply outputs the transformed text (and if you need to save it to a file, remember that output redirection is a thing!). -
sedis able to read from a file as an argument or as redirected input e.g.sed ’s//’ fileorsed ’s//’ < file. -
Try using a backreference!
-
Keep in mind
sed’sscommand will replace what got matched as a whole: try matching against the whole comment, slashes and all, then replacing it with the correct kind of comment.
-
-
To test if the replacement worked, try compiling the files with the
-std=c89flag. (By the way, deleting the comments aren’t a solution; we can check to see if the actual comment messages are still there :p) -
Stage and commit the finished
c89ify.shscript.
Conclusion
-
Add and commit any changes you intend to submit.
-
Create a file called
report.txt. -
On the first line provide an integer time in minutes of how long it took for you to complete this assignment.
-
On the second line and beyond, write down what you learned while doing this assignment. If you already knew how to do all of this, put down “N/A”.
-
Add and commit this
report.txtfile.