Skip to main content

Build Your Own cat Tool

This challenge is to build your own version of the Unix Command line tool cat.

The Unix command line tools are a great metaphor for good software engineering and they follow the Unix Philosophies of:

  • Writing simple parts connected by clean interfaces - each tool does just one thing and provides a simple CLI that handles text input from either files or file streams.
  • Design programs to be connected to other programs - each tool can be easily connected to other tools to create incredibly powerful compositions.

Following these philosophies has made the simple Unix command line tools some of the most widely used software engineering tools - allowing us to create very complex text data processing pipelines from simple command line tools.

The Challenge - Building Your Own cat Tool

Let’s check out the man page on cat to find out what it does:

The cat utility reads files sequentially, writing them to the standard output.
The file operands are processed in command-line order. If file is a single
dash (‘-’) or absent, cat reads from the standard input.

Step Zero

Like most programming languages we’re zero indexed!

For this step, I’ll leave you to setup your IDE / editor of choice and programming language of choice. After that here’s what I’d like you to do to be ready to test your solution.

Then let’s grab some quotes to use as test data:

% curl "https://dummyjson.com/quotes?limit=10" | jq '.quotes | .[] | .quote' > test.txt
% curl "https://dummyjson.com/quotes?limit=10&skip=10" | jq '.quotes | .[] | .quote' > test2.txt

Step 1

In this step your goal is to open the file specified on the command line and write its contents to standard out. That should look something like this (I’m assuming you call your program cccat:

% cccat test.txt
"Life isn’t about getting and having, it’s about giving and being."
"Whatever the mind of man can conceive and believe, it can achieve."
"Strive not to be a success, but rather to be of value."
"Two roads diverged in a wood, and I—I took the one less traveled by, And that has made all the difference."
"I attribute my success to this: I never gave or took any excuse."
"You miss 100% of the shots you don’t take."
"I’ve missed more than 9000 shots in my career. I’ve lost almost 300 games. 26 times I’ve been trusted to take the game winning shot and missed. I’ve failed over and over and over again in my life. And that is why I succeed."
"The most difficult thing is the decision to act, the rest is merely tenacity."
"Every strike brings me closer to the next home run."
"Definiteness of purpose is the starting point of all achievement."

Step 2

In this step your goal is to read the input from from standard in, you can test it like this:

% head -n1 test.txt | cccat -
"Life isn’t about getting and having, it’s about giving and being."

Step 3

In this step your goal is to concatenate files. You can test your program like this:

% cccat test.txt test2.txt
"Life isn’t about getting and having, it’s about giving and being."
"Whatever the mind of man can conceive and believe, it can achieve."
"Strive not to be a success, but rather to be of value."
"Two roads diverged in a wood, and I—I took the one less traveled by, And that has made all the difference."
"I attribute my success to this: I never gave or took any excuse."
"You miss 100% of the shots you don’t take."
"I’ve missed more than 9000 shots in my career. I’ve lost almost 300 games. 26 times I’ve been trusted to take the game winning shot and missed. I’ve failed over and over and over again in my life. And that is why I succeed."
"The most difficult thing is the decision to act, the rest is merely tenacity."
"Every strike brings me closer to the next home run."
"Definiteness of purpose is the starting point of all achievement."
"We must balance conspicuous consumption with conscious capitalism."
"Life is what happens to you while you’re busy making other plans."
"We become what we think about."
"Twenty years from now you will be more disappointed by the things that you didn’t do than by the ones you did do, so throw off the bowlines, sail away from safe harbor, catch the trade winds in your sails. Explore, Dream, Discover."
"Life is 10% what happens to me and 90% of how I react to it."
"The most common way people give up their power is by thinking they don’t have any."
"The mind is everything. What you think you become."
"The best time to plant a tree was 20 years ago. The second best time is now."
"An unexamined life is not worth living."
"Eighty percent of success is showing up."

Step 4

In this step your goal is to number the lines as they’re printed out, that should look like this:

% head -n3 test.txt | cccat -n
1 "Life isn’t about getting and having, it’s about giving and being."
2 "Whatever the mind of man can conceive and believe, it can achieve."
3 "Strive not to be a success, but rather to be of value."

Free free not to use head, I’m just keeping the example short.

Step 5

In this step your goal is to number lines, both including and excluding non-blank lines, here’s a couple of test cases:

% sed G test.txt | cccat -n | head -n4
1 "Life isn’t about getting and having, it’s about giving and being."
2
3 "Whatever the mind of man can conceive and believe, it can achieve."
4

and:

% sed G test.txt | cccat -b | head -n5
1 "Life isn’t about getting and having, it’s about giving and being."

2 "Whatever the mind of man can conceive and believe, it can achieve."

3 "Strive not to be a success, but rather to be of value."

Here we’ve used sed G to add extra blank lines.

If you’ve got this far, congratulations you’ve built your own version of cat.

Help Others by Sharing Your Solutions!

If you think your solution is an example other developers can learn from please share it, put it on GitHub, GitLab or elsewhere. Then let me know - ping me a message on the Discord Server or in the Coding Challenges Sub Reddit, via Twitter or LinkedIn or just post about it there and tag me.

Get The Challenges By Email

If you would like to recieve the coding challenges by email, you can subscribe to the weekly newsletter on SubStack here: