Find credit card numbers and replace characters at set positions - sed

I have a file that contains credit card numbers (16 characters), I want to find them and replace everything with "X" apart from the first 6 and last 4 numbers.
sed -i 's/\([345]\{1\}[0-9]\{3\}\|6011\)\{1\}[ -]\?[0-9]\{4\}[ -]\?[0-9]\{2\}[-]\?[0-9]\{2\}[ -]\?[0-9]\{1,4\}/\XXXXXX/g' foobar.csv
Will easily find all credit cards contained in the file and replace them with "XXXX"
But I want to find the credit cards and replace only characters 7-12 of the string with "X", so the file will contain credits which are masked like this 123456XXXXXX7890.
Sample input line:
jam peanut boat handbag on the shore in Tuesday 4548640040302006 in the morning jimmy
Sample output line:
jam peanut boat handbag on the shore in Tuesday 454864XXXXXX2006 in the morning jimmy

Try this with GNU sed to anonymize credit card numbers:
sed -i 's/\(\([345]\{1\}[0-9]\{3\}\|6011\)\{1\}[ -]\?[0-9]\{2\}\)[0-9]\{2\}[ -]\?[0-9]\{2\}[-]\?[0-9]\{2\}[ -]\?\([0-9]\{1,4\}\)/\1XXXXXX\3/g' file
Input:
jam peanut boat handbag on the shore in Tuesday 4548640040302006 in the morning jimmy
jam peanut boat handbag on the shore in Tuesday 454864XXXXXX2006 in the morning jimmy
Output to file:
jam peanut boat handbag on the shore in Tuesday 454864XXXXXX2006 in the morning jimmy
jam peanut boat handbag on the shore in Tuesday 454864XXXXXX2006 in the morning jimmy

Related

Finding Palm Sunday

Palm Sunday is the Sunday before Easter Sunday. Finding Easter Sunday can be achieved with:
use Time::Moment;
use Time::Moment::Adjusters qw(WesternEasterSunday PreviousDayOfWeek);
# 2018-04-01T00:00:00Z
my $easter_sunday = Time::Moment->new(year => 2018)->with(WesternEasterSunday);
Finding the Sunday before that could be achieved with Time::Moment::Adjusters' PreviousDayOfWeek(7):
$adjuster = PreviousDayOfWeek($day);
The $adjuster adjusts the date to the previous occurrence of the given day of the week [1=Monday, 7=Sunday] that is before the date.
But if I apply this adjuster, I get a Tuesday five days earlier!
# 2018-03-27T00:00:00Z
my $palm_sunday = $easter_sunday->with(PreviousDayOfWeek(7))
Since Palm Sunday is always seven days prior to Easter Sunday, I could achieve this with Time::Moment's minus_days(7), but since I want to find a number of other holidays that are much simpler to find using Time::Moment::Adjusters, I would really like to find the root of this unexpected behavior.
Thank you Simon for the report and the PR and thank you #simbabque for the test! I have shipped v0.44 to CPAN. You are excellent citizens in the opensource community!
--
chansen

SED and/or awk help required

I am using openvms but have access to versions of aWk and /or sed on this platform. Wondered if anyone can help with a text file processing job.
My file looks like
START-OF-DATA
Stock ID|XYZ
START-TIME 11:30
END_TIME 12:30
11:31|BID|12.5|ASK|12.7
11:34|BID|12.6|ASK|12.7
END-OF-DATA
START-OF-DATA
Stock ID|ABC
START-TIME 11:30
END_TIME 12:30
11:40|BID|.245|ASK|.248
11:34|BID|.246|ASK|.249
END-OF-DATA
Basically I want to pre-pend the BID/ASK data records with the Stock ID so the above file should look like
START-OF-DATA
Stock ID|XYZ
START-TIME 11:30
END_TIME 12:30
XYZ|11:31|BID|12.5|ASK|12.7
XYZ|11:34|BID|12.6|ASK|12.7
END-OF-DATA
START-OF-DATA
Stock ID|ABC
START-TIME 11:30
END_TIME 12:30
ABC|11:40|BID|.245|ASK|.248
ABC|11:34|BID|.246|ASK|.249
END-OF-DATA
Can any one help ?
Like this:
awk -F'|' 'BEGIN{OFS="|"} /^Stock/{S=$2} /BID|ASK/{print S,$0}' file
Explanation (with thanks to Olivier Dulac)
It updates "S" variable each time it encounters a line stating with "Stock", and then prepends S to lines CONTAINING "BID" or "ASK" (using | as a separator for reading and for outputting).
try this:
awk -F'|' 'NF==2{pre=$2}NF>2{$0=pre FS $0}7' file
it works for the given example.
Using awk
awk '/Stock ID/{s=$2}/BID|ASK/{$0=s FS $0}1' FS=\| file
START-OF-DATA
Stock ID|XYZ
START-TIME 11:30
END_TIME 12:30
XYZ|11:31|BID|12.5|ASK|12.7
XYZ|11:34|BID|12.6|ASK|12.7
END-OF-DATA
START-OF-DATA
Stock ID|ABC
START-TIME 11:30
END_TIME 12:30
ABC|11:40|BID|.245|ASK|.248
ABC|11:34|BID|.246|ASK|.249
END-OF-DATA
This might work for you (GNU sed):
sed -r '/Stock ID/h;/BID|ASK/{G;s/(.*)\n.*\|(.*)/\2|\1/}' file
Save the Stock ID in the hold space and prepend it to records containing BID or ASK.

What am I doing wrong while importing the following data into sas

I am trying to import certain data into my SAS datset using this piece of code:
Data Names_And_More;
Infile 'C:\Users\Admin\Desktop\Torrent Downloads\SAS 9.1.3 Portable\Names_and_More.txt';
Input Name & $20.
Phone : $20.
Height & $10.
Mixed & $10.;
run;
The data in the file is as below:
Roger Cody (908)782-1234 5ft. 10in. 50 1/8
Thomas Jefferson (315)848-8484 6ft. 1in. 23 1/2
Marco Polo (800)123-4567 5Ft. 6in. 40
Brian Watson (518)355-1766 5ft. 10in 89 3/4
Michael DeMarco (445)232-2233 6ft. 76 1/3
I have been trying to learn SAS and while going through Ron Cody's book Learning SAS by example,I found to import the kind of data above, we can use 'the ampersand (&) informat modifier. The ampersand, like the colon,says to use the supplied informat, but the delimiter is now two or more blanks instead of just one.' (Ron's words, not mine). However, while importing this the result (dataset) is as follows:
Name Phone Height Mixed
Roger Cody (908)782- Thomas Jefferson Marco Polo
Also, for further details the SAS log is as follows:
419 Data Names_And_More;
420 Infile 'C:\Users\Admin\Desktop\Torrent Downloads\SAS 9.1.3 Portable\Names_and_More.txt';
421 Input Name & $20.
422 Phone : $20.
423 Height & $10.
424 Mixed & $10.
425 ;run;
NOTE:
The infile 'C:\Users\Admin\Desktop\Torrent Downloads\SAS 9.1.3 Portable\Names_and_More.txt' is:
File Name=C:\Users\Admin\Desktop\Torrent Downloads\SAS 9.1.3 Portable\Names_and_More.txt,
RECFM=V,LRECL=256
NOTE:
LOST CARD.
Name=Brian Watson (518)35 Phone=Michael Height=DeMarco (4 Mixed= ERROR=1 N=2
NOTE: 5 records were read from the infile 'C:\Users\Admin\Desktop\Torrent Downloads\SAS 9.1.3
Portable\Names_and_More.txt'.
The minimum record length was 37.
The maximum record length was 47.
NOTE: SAS went to a new line when INPUT statement reached past the end of a line.
NOTE: The data set WORK.NAMES_AND_MORE has 1 observations and 4 variables.
NOTE: DATA statement used (Total process time):
real time 0.17 seconds
cpu time 0.14 seconds
I am looking for some help with this one. It'd be great if someone can explain what exactly is happening, what am I doing wrong and how to correct this error.
Thanks
The answer is in the explanation in Ron Cody's book. & means you need two spaces to separate varaibles; so you need a second space after the name (and other fields with &).
Wrong:
Roger Cody (908)782-1234 5ft. 10in. 50 1/8
Right:
Roger Cody (908)782-1234 5ft. 10in. 50 1/8

BASH: comm (or similar) when compare multiple files

I've the following problem: I would like to compare the content of 8 files contaning a list like this
Sample1.txt Sample2.txt Sample3.txt
apple pineapple apple
pineapple apple pineapple
bananas bananas bananas
orange orange mango
grape nuts nuts
using comm Sample1.txt Sample 2.txt I can have something like this
grape nuts apple
pineapple
bananas
orange
meaning that in the first column I have something related only to the first sample, the second column the things related only to the second sample and the third column the things in common.
I would like to do the same but with 8 files (sample). With diff it is not possible but at the end I would like to have
Sample1 Sample2 Sample3 ...Sample8 Things in common
grape nuts mango apple
pineapple
bananas
Is there a chance to do it with bash? Is there a command like diff that allow the searching for differences on more than two files?
Thank you to everybody...I know this is a challenging question
Fabio
Here is my naive solution:
first=sample1.txt; for a in *.txt; do comm -12 $first $a >temp_$a; echo "comparing" $first " " $a "and writing to temp_$a"; first=temp_$a; cat temp_$a; done;

print column and count the string

I have large column wise text file with space demlimited
Name subject Result
John maths pass
John science fail
John history pass
John geography pass
Jack maths pass
jack history fail
kelly science pass
kelly history pass
I want to count for each name (it is long name list, each name should be appear only once), how many of them pass. For eg. For John, he passed 3 and similarily for Jack he passed 1. It should print the result as
Name Passcount
John 3
Jack 1
Kelly 2
Can anybody can help with awk or perl script. Thanks in advance
You can try something like this -
awk '
BEGIN{ print "Name\tPasscount"}
NR>1{if ($3=="pass") a[$1]++}
END{ for (x in a) print x"\t"a[x]}' file
Test:
$ cat file
Name subject Result
John maths pass
John science fail
John history pass
John geography pass
Jack maths pass
jack history fail
kelly science pass
kelly history pass
$ awk 'BEGIN{ print "Name\tPasscount"} NR>1{if ($3=="pass") a[$1]++}END{ for (x in a) print x"\t"a[x]}' file
Name Passcount
Jack 1
kelly 2
John 3