Hey there people on the internet. Here's my solution for Sed Command - 4 Linux shell challenge from HackerRank. You can find answers to other Linux shell challenges via this link => https://blog.shasec.rocks/post/hackerrank-bash-challs. So let's get started.
Challenge
Sed is a popular tool that enables quick parsing and transformation of text.
Examples of sed in action:
Substitute the first occurrence of 'editor' with 'tool':
`$:~/hackerrank/bash/grep/grep1$` echo "My favorite programming editor is Emacs. Another editor I like is Vim." | sed -e s/editor/tool/
My favorite programming tool is Emacs. Another editor I like is Vim.
Substitute all the occurrences of 'editor' with 'tool':
`$:~/hackerrank/bash/grep/grep1$` echo "My favorite programming editor is Emacs. Another editor I like is Vim." | sed -e s/editor/tool/g
My favorite programming tool is Emacs. Another tool I like is Vim.
Substitute the second occurrence of 'editor' with 'tool':
`$:~/hackerrank/bash/grep/grep1$` echo "My favorite programming editor is Emacs. Another editor I like is Vim." | sed -e s/editor/tool/2
My favorite programming editor is Emacs. Another tool I like is Vim.
Highlight all the occurrences of 'editor' by wrapping them up in brace brackets:
`$:~/hackerrank/bash/grep/grep1$` echo "My favorite programming editor is Emacs. Another editor I like is Vim." | sed -e s/editor/{\&}/g
My favorite programming {editor} is Emacs. Another {editor} I like is Vim.
> Task
Given n lines of credit card numbers, mask the first 12 digits of each credit card number with an asterisk (i.e., *) and print the masked card number on a new line. Each credit card number consists of four space-separated groups of four digits. For example, the credit card number 1234 5678 9101 1234 would be masked and printed as **** **** **** 1234.
> References
You may find the following links helpful in learning about sed:
- Sed - An Introduction and a tutorial
- The TLDP Guide
- Some Practical Examples
- A StackOverflow question on a slightly modified version of this task where the solution involves backreferences.
- A tutorial from TheGeekStuff detailing the use of groups and backreferences.
> Input Format
Each line contains a credit card number in the form dddd dddd dddd dddd, where d denotes a decimal digit (i.e., 0 through 9). There are a total of n lines of credit card numbers.
> Constraints
1 <= n <= 20; note that the value of n does not matter when writing your command.
> Output Format
For each credit card number, print its masked version on a new line.
> Sample Input
1234 5678 9101 1234
2999 5178 9101 2234
9999 5628 9201 1232
8888 3678 9101 1232
> Sample Output
**** **** **** 1234
**** **** **** 2234
**** **** **** 1232
**** **** **** 1232
> Explanation
Observe that the first twelve digits have been masked for each credit card number, and they are printed in the same order as they were received as input.
Solution
I used awk command to do this challenge which is far more easier than sed. At least for me :).
#!/bin/bash
awk '{
print "****","****","****",$4
}'
For anyone who wants the sed version of my solution here it is. But I do want to mention that I guess this solution is not optimized. I just used it to get the job done. Plus, I understand what's going on compared to other complex regex patterns.
The idea is you check the first 4 digit chunks and replace them with "****". This is only for a single occurrence. To get all the 3 chunks like this (**** **** ****). I just piped it 2 more times.
#!/bin/bash
sed -r 's/[0-9]{4}/****/' | sed -r 's/[0-9]{4}/****/' | sed -r 's/[0-9]{4}/****/'

💬 Comment Section 💬