I’m a member of this amazing online community called Virtual Coffee. We meet twice a week and have conversations about the tech industry as well as tech-adjcent topics. In today’s meeting, we kept coming back to reducing project anxiety by breaking large tasks down into several smaller ones. It reminded me of a quote I revisit often when I feel overwhelmed:
The person who removes a mountain begins by carrying away small stones. —Chinese Proverb
In fact, I have a whole file filled with quotes I pick up here and there that bring me joy and inspiration. I’ve created a bash script which outputs one quote at random from this file every time I start up a new terminal session. After sharing this with my Virtual Coffee group, they were eager to learn how I did it, so here’s a step-by-step write up for you to create a random quote generator of your own!
The Script
Add the following quote
function to your .bash_profile and call it just above the line where you define export PS1
:
function quote {
# Set the file path to the quotes file
quote_file=$HOME/Development/code/quotes.txt
# Retrieve a random quote for the file
sed -n $(awk "END{ print $RANDOM%NR+1}" $quote_file)p $quote_file
}
# This function builds your prompt. It is called below:
function prompt {
# Call the quote function inside your prompt function and it prints a quote to your terminal
quote
# Here is where we actually export the PS1 variable which stores the text for your prompt
export PS1
}
# Call the prompt function
prompt
If you don’t have a prompt
function defined where you export your PS1
variable, you should do so. This allows your quote to be printed out just before your regular bash prompt.
A Breakdown of the Above
The quote_file
variable is a path to the simple text file where my list of quotes are stored. Depending on your editor (I use Mac’s default, TextEdit), the quotes may wrap. That’s okay as long as you start each new quote on a separate line.
Edge Case: Leave a blank new line at the end of your text file. If the last quote in your file is randomly selected, the PS1
in your terminal will appear on the same line directly after the quote if you don’t do this!
This snippet awk "END{ print $RANDOM%NR+1}" $quote_file
is actually using the AWK scripting language! This denotes that we’re executing the action { print $RANDOM%NR+1}
for the pattern END
on the file represented by the variable $quote_file
(as defined on the line above it). END
counts the number of lines in the entire $quote_file
document. Then NR
returns the specified row number, which in this case is that of the last line as denoted by END
, and the result of $RANDOM%NR+1
is printed out. $RANDOM
is a built-in bash variable that returns a random integer, which we use as the numberator to NR
’s denominator to return a remainder using the modulo operation (%
).
Edge Case: After the remainder is calculated, we increment by one. Doing this accounts for a remainder of zero and ensures that a quote will always be returned.
Do you see how that whole code snippet is encapsulated in $()
? Let’s take the number we just returned and assign it to the variable modulo
for the rest of this breakdown.
Now what we’re left with is sed -n $(modulo)p $quote_file
. sed
isn’t bash—sed
is actually a Unix utility called a stream editor! And like AWK, we can pass it options before passing the input file. By default, sed
prints out all processed input so we use -n
to suppress output and p
to print specific lines. We already know from above that modulo
is a random number that maps to the number of lines in your quote text file, therefore, you should see a random quote from your file print to the terminal!
I also have a pretty little bash prompt that shows me where I am in my directory, has custom colors, and displays git repos and branches. If you want to know more about this setup, DM me on Twitter @meg_gutshall!