Advanced Lab 1
A Note on Labs
Labs are graded on completion. Treat this lab as seeds of exploration instead
of just a grade.
As this is the first lab, we have done our best to make it as straightforward as possible. Bash scripting
isn’t the main goal of the DeCal but this lab should introduce you to some fun bash features you may not have encountered before, such as loops and shell expansions, that you’ll probably find useful in the future.
If you ever find yourself confused, stuck, and/or curious to learn more, talk to us about it! The best way to connect with us (and your peers) is through our Slack channel.
Workflow
This lab can be done on your own UNIX-like machine, or you can ssh into
tsunami.ocf.berkeley.edu
using your OCF account to finish the lab there. As always,
man
and Google will be your friends.
Question 1
At some point, everyone has looked at a problem and thought to themselves:
“Hey, I can do this in one line!”
Lets find out if you can. I need to sort out some of my most listened to albums
by making directories for each of them, specifically for my favorite artist Future.
I have hosted a list of my favorite albums followed by their respective artist at
https://raw.githubusercontent.com/0xcf/decal-labs/master/a1/albums.txt
,
in a comma delimited format like Die Lit, Playboi Carti
. For the GOAT artist Future,
I want to create a folder for each of his albums. For example, for an entry like
SUPER SLIMEY, Future
I would expect a directory called SUPER SLIMEY
to be created.
TLDR: You need to fetch the list from the web, filter out the albums we want,
trim out the album name, and then make a directory for each one, all in one line.
$ cat albums.txt
...
Drip or Drown 2, Gunna
Playboi Carti, Playboi Carti
DS2 (Deluxe), Future <-- GOAT album detected!
Drip Harder, Lil Baby
The WIZRD, Future <-- GOAT album detected!
What a Time To Be Alive, Drake
...
# After our magic one liner...
$ ls
'DS2 (Deluxe)' 'The WIZRD` ...
# We got our new directories!
Hints:
- What common text manipulation commands can help you solve this?
- As always, be aware that there isn’t one unique solution to this problem!
- Also be aware that
xargs
behaves differently on different platforms.
Submit your one line solution!
Question 2
With the invention of the .norm
file format, file extension innovation is at its peak!
However, your computer is old and doesn’t support it, so we’ll need to convert all of the files ending in .norm
into .docx
files.
Using Bash functions and shell wildcard expansion, write a
shell script rename.sh
to batch rename file extensions in a particular directory.
Example:
$ ls Documents/
cats.norm data.norm dogs.norm ...
$ ./rename Documents norm docx # Run your script!
renaming Documents/data.norm to Documents/data.docx
renaming Documents/cats.norm to Documents/cats.docx
renaming Documents/dogs.norm to Documents/dogs.docx
...
$ ls Documents/
cats.docx data.docx dogs.docx ...
Your script should be able to convert between any arbitrary file formats, not just .norm
and .docx
! For example:
$ ls
# Creates a new directory tmp and adds 26 new files a.dat, b.dat ... to z.dat into it
$ mkdir tmp && touch tmp/{a..z}.dat
$ ./rename.sh tmp dat txt
renaming tmp/a.dat to tmp/a.txt
...
renaming tmp/z.dat to tmp/z.txt
$ ls -lAh tmp | grep .txt | wc -l # Gets the number of lines in ls which contain .txt
26
for bonus points, instead of using something like sed
to affect the rename,
use shell parameter expansion.
Question 3
I like Lisp and Scheme, and miss car
and cdr
in my usual programming tasks.
In bash, implement car
and cdr
(aka head
and tail
) such that they
operate on file paths.
e.g.
$ ./car /home/a/ab/abizer/some/path
home
$ ./cdr /home/a/ab/abizer/some/path
a/ab/abizer/some/path
There’s no need to use complicated string manipulation for this task.
You may assume that only absolute paths will be given.
bonus points: generalize this solution to work for cadr
, caddr
, etc.
$ ./cadr /home/a/ab/abizer/some/path
a
$ ./cddr /home/a/ab/abizer/some/path
ab/abizer/some/path
Hint: The easiest way to do this is with one very short command.
This question is optional but it’s quite fun and you should do it if you have the time!
Using Bash functions, write a script mkrandom.sh
that generates a user-specified number
of files of user-specified size filled with random content.
e.g.
$ ./mkrandom.sh 10 100 # create 10 100 byte random files
$ ls -lAh
total 44K
-rw-r--r-- 1 abizer ocf 100 Sep 16 21:57 1
-rw-r--r-- 1 abizer ocf 100 Sep 16 21:57 10
-rw-r--r-- 1 abizer ocf 100 Sep 16 21:57 2
-rw-r--r-- 1 abizer ocf 100 Sep 16 21:57 3
-rw-r--r-- 1 abizer ocf 100 Sep 16 21:57 4
-rw-r--r-- 1 abizer ocf 100 Sep 16 21:57 5
-rw-r--r-- 1 abizer ocf 100 Sep 16 21:57 6
-rw-r--r-- 1 abizer ocf 100 Sep 16 21:57 7
-rw-r--r-- 1 abizer ocf 100 Sep 16 21:57 8
-rw-r--r-- 1 abizer ocf 100 Sep 16 21:57 9
-rwxr-xr-x 1 abizer ocf 147 Sep 16 21:56 mkrandom
You may want to look into dd
and the iflag=fullblock
argument,
seq
, and /dev/random
.
Submission
Submit your solutions on Gradescope! There’ll be some extra feedback questions as well that we would appreciate you filling out.