Build Your Own WC Tool in NodeJS 💻
Introduction
In this blog, we will see how to create your own Linux WC tool in NodeJs. This project is a part of the Coding Challenge (here).
What is the WC tool?
The wc
(word count) tool is a command-line utility in Unix and Linux systems that displays the number of lines, words, and bytes in a file or input.
The traditional wc tool is written in C
language.
Here, 9 lines, 20 words, and 128 characters present in the test.txt
.
How to build a WC tool in NodeJS?
Step 1: Set up the environment
Ensure you have Node.js installed on your system. You can download it from Node.js official website.
Step 2: Install npm and Import modules
Initialize a new Node.js project:
npm init -y
Install the necessary modules:
npm install commander fs
Create a new file
index.js
inside a bin folder and import the required modules:const { readFileSync } = require('fs'); // To handle files const { program } = require('commander'); // To create a cli command
Step 3: Create cawc
command and Parse the input
Provide your own cli command name and its description using program.command()
, program.description()
. This will create a cli command for you.
To define flag options in your cli command, use program.option()
to define the different flag options for your command. Here, I defined four flag options for my cawc
command.
The
-l or --line
flag will take the file name as an input and returns the number of lines in the given file.The
-w or --word
flag will take the file name as an input and returns the number of words in the given file.The
-m or --chars
flag will take the file name as an input and return the number of characters in the given file.The
-c or --bytes
flag will take the file name as an input and return the number of bytes in the given file.
The program.parse()
is used to parse the args
in cli command, and using program.opts()
we can separate the options (i.e., flag) from the command statement.
// Command is defined
program
.command('cawc')
.description('Return the number of lines, words, character present in the file.');
// Command options are defined
program
.option('-l, --line <FILENAME>', 'Returns the number of lines in a file')
.option('-w, --word <FILENAME>', 'Returns the number of words in a file')
.option('-m, --chars <FILENAME>', 'Returns the number of characters in a file')
.option('-c, --bytes <FILENAME>', 'Returns the number of bytes in a file');
// .args('<FILENAME>');
// Input
program.parse(process.argv);
const options = program.opts();
Step 4: Define function for -l or --line
flag
When the -l or --line
flag is used, then the command should return the number of lines present in the given file. The below function is used to return the number of lines present in the file.
Here, options.line
stores the file name and sends it to the noOfLines()
function to read it. readFileSync()
is used to read the file.
// If flag is -l call the noOfLines function
if (options.line) console.log(noOfLines(options.line)+" "+options.line) ;
// Option -l is chosen
function noOfLines(file_name){
// ReadFileSync function is used to read the file and convert it
// into string using toString() method
var text = readFileSync(file_name).toString();
// The text is splitted by new line and the length is found using length
var lineCount = text.split('\n').length;
// Formatted output
return lineCount;
}
Step 5: Define function for -w or --word
flag
When the -w or --word
flag is used, then the command should return the number of words present in the given file. The below function is used to return the number of words present in the file.
// If flag is -w call the noOfWords function
if (options.word) console.log(noOfWords(options.word)+" "+options.word);
// Option -w is chosen
function noOfWords(file_name){
var wordCount = 0;
// Read the contents of file and separate it line by line
var text = readFileSync(file_name).toString().split('\n');
// Iterate through each line to find the number of words in each line
for(const line of text){
// Add it to the wordCount
wordCount += line.split(' ').length;
}
// Format the output
return wordCount;
}
Step 6: Define function for -m or --chars
flag
When the -m or --chars
flag is used, then the command should return the number of characters present in the given file. The below function is used to return the number of characters present in the file.
// If flag is -m call the noOfChars function
if (options.chars) console.log(noOfChars(options.chars)+" "+options.chars);
// Option -m is chosen
function noOfChars(file_name){
// Find the number of characters in the file
var charCount = readFileSync(file_name).toString().length;
// Format the output
return charCount;
}
Step 7: Define function for -c or --bytes
flag
When the -c or --bytes
flag is used, then the command should return the number of bytes present in the given file. The below function is used to return the number of bytes present in the file.
// If flag is -c call the noOfBytes function
if (options.bytes) console.log(noOfBytes(options.bytes)+" "+options.bytes);
// Option -c is chosen
function noOfBytes(file_name){
// Find the number of bytes in the file
var byteCount = readFileSync(file_name).length;
// Format the output
return byteCount;
}
Step 8: Define function without flag
When no flag is used, then the command should return the number of lines, words and characters present in the given file.
// console.log(program.args);
if (process.argv.length < 5) defaultCall(process.argv[3]);
// File name only provided
function defaultCall(file_name){
// Get number of lines
var lines = noOfLines(file_name);
// Get number of words
var words = noOfWords(file_name);
// Get number of characters
var characters = noOfChars(file_name);
// Format output
console.log(lines+" "+words+" "+characters+" "+file_name);
}
Final index.js
file
The final index.js
file should look like this.
#! /usr/bin/env node
// Module import
const { program } = require('commander');
const { readFileSync } = require('fs');
// Command is defined
program
.command('cawc')
.description('Return the number of lines, words, character present in the file.');
// Command options are defined
program
.option('-l, --line <FILENAME>', 'Returns the number of lines in a file')
.option('-w, --word <FILENAME>', 'Returns the number of words in a file')
.option('-m, --chars <FILENAME>', 'Returns the number of characters in a file')
.option('-c, --bytes <FILENAME>', 'Returns the number of bytes in a file');
// .args('<FILENAME>');
// Input
program.parse(process.argv);
const options = program.opts();
// If flag is -l call the noOfLines function
if (options.line) console.log(noOfLines(options.line)+" "+options.line) ;
// If flag is -w call the noOfWords function
if (options.word) console.log(noOfWords(options.word)+" "+options.word);
// If flag is -m call the noOfChars function
if (options.chars) console.log(noOfChars(options.chars)+" "+options.chars);
// If flag is -c call the noOfBytes function
if (options.bytes) console.log(noOfBytes(options.bytes)+" "+options.bytes);
// console.log(program.args);
if (process.argv.length < 5) defaultCall(process.argv[3]);
// else {}
// Option -l is chosen
function noOfLines(file_name){
// ReadFileSync function is used to read the file and convert it
// into string using toString() method
var text = readFileSync(file_name).toString();
// The text is splitted by new line and the length is found using length
var lineCount = text.split('\n').length;
// Formatted output
return lineCount;
}
// Option -w is chosen
function noOfWords(file_name){
var wordCount = 0;
// Read the contents of file and separate it line by line
var text = readFileSync(file_name).toString().split('\n');
// Iterate through each line to find the number of words in each line
for(const line of text){
// Add it to the wordCount
wordCount += line.split(' ').length;
}
// Format the output
return wordCount;
}
// Option -m is chosen
function noOfChars(file_name){
// Find the number of characters in the file
var charCount = readFileSync(file_name).toString().length;
// Format the output
return charCount;
}
// Option -c is chosen
function noOfBytes(file_name){
// Find the number of bytes in the file
var byteCount = readFileSync(file_name).length;
// Format the output
return byteCount;
}
// File name only provided
function defaultCall(file_name){
// Get number of lines
var lines = noOfLines(file_name);
// Get number of words
var words = noOfWords(file_name);
// Get number of characters
var characters = noOfChars(file_name);
// Format output
console.log(lines+" "+words+" "+characters+" "+file_name);
}
Example Usage
To run the command, navigate to the bin folder and run the below command. Where, test.txt
is a test file present in the bin folder.
node index.js cawc test.txt
You can also use custom file to run this command.
node index.js cawc file_path
Screenshots
Output using test file present in bin folder
Output using custom file location
Conclusion
Hurray! Your cli command was created successfully. Comment on this blog to clarify your doubts.
Resources
Subscribe to my newsletter
Read articles from Roopa directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Roopa
Roopa
I'm a pre-final year computer science student at SRM with a strong academic background and technical skills. I am actively contributing to the beginner-friendly open-source repositories to showcase my skills in web development. I love to share my knowledge of technical skills and am a pro at debugging errors.