So I have a task to mask the first 12 digits of each credit card number with an asterisk (*) given an input file and print the masked number to an output file!
Example card numbers:
1111-2222-3333-4444
4444-3333-2222-1111
1234-5678-9101-1171
1234 5678 9101 1121
7347_9834_7598_2834
8973#9858#3475#8734
2356`7843`0527`5340
8734=7583=4895=7007
8763 2430 6257_9406
Everything should be done in a shell script
My solution is:
#!/bin/bash
file='cards.txt'
while read data; do
echo $data | sed -r 's/[[:digit:]]{4}/****/;s/[[:digit:]]{4}/****/;s/[[:digit:]]{4}/****/;s/[^0-9,*] / /g'
done < $file > cards-masked.txt
Any better ideas on how to use sed in this task?
CodePudding user response:
It is much simple:
cat cards.txt|rev|sed -e 's/[[:digit:]]/*/5g' |rev > cards-masked.txt
echo "1234-5678-9123-1234"|rev|sed -e 's/[[:digit:]]/*/5g' |rev
****-****-****-1234
This one is reverse task:
cat cards.txt|sed -e 's/[[:digit:]]/*/13g' > cards-masked.txt
As you can see there is no need in while/read loop too. Each one sed expression will be evaluated per-line.
CodePudding user response:
This might work for you (GNU sed):
sed -E '/([0-9]{4}[ #`= -_]){3}[0-9]{4}/{s//\n&\n/;h
s/[0-9]/*/g;G;s/.*\n(.*)\n.*\n(.*)\n.*\n/\2\1/}' file
Surround a match by newlines.
Make a copy.
Replace all digits by *
's
Append the copy.
Using pattern matching, replace the original match by the amended match.
Can be extended for multiple matches on a line:
sed -E ':a;/([0-9]{4}[ #`= -_]){3}[0-9]{4}/{s//\n&\n/;h
s/[0-9]/*/g;G;s/.*\n(.*)\n.*\n(.*)\n.*\n/\2\1/;ta}' file
To replace only the first nine digits, use:
sed -E ':a;/(([0-9]{4}[ #`= -_]){3})([0-9]{4})/{s//\n\1\n\3/;h
s/[0-9]/*/g;G;s/.*\n(.*)\n.*\n(.*)\n.*\n/\2\1/;ta}' file
CodePudding user response:
1st solution: Using simple sed
perform substitution 3 times of 4 digits to 4 *
each time and you are all set.
sed -E 's/[[:digit:]]{4}/****/;s/[[:digit:]]{4}/****/;s/[[:digit:]]{4}/****/' Input_file
2nd solution: With awk
program it could be simply done by using 3 times sub
(substitute) function.
awk '{sub(/[[:digit:]]{4}/,"****");sub(/[[:digit:]]{4}/,"****");sub(/[[:digit:]]{4}/,"****")} 1' Input_file