'How to select two columns from awk and print if they do not match
I need to select two MSISDN values from OMO account Migration logs and print the ones that do not match.
[2019-03-11 04:15:08 INFO-SUBAPP ESBRestClient:117] ## IP-103.228.158.85##TOKEN-201903110416276787774(**923419606907**)RESPONSE-BODY: {"callStatus":"false","responseCode":"18","description":"OMO account migration – **923481057772**"}
[2019-03-11 04:24:02 INFO-SUBAPP ESBRestClient:117] ## IP-119.153.134.128##TOKEN-1552260212780839(923214748517)RESPONSE-BODY: {"callStatus":"false","responseCode":"18","description":"OMO account migration – 953214748517"}
923481057772
is the old MSISDN.
923419606907
is the new MSISDN and I need to save it in a new file. I'm was using the following command to select only the new MSISDN:
cat migration.txt | egrep "OMO account migration" | egrep "responseCode\":\"1700" | awk -F"(" '{gsub(/\).*/,"",$2);print $2}' >>newmsisdn.txt
I'm using the saved msisdn values to fetch the token number. Then I'm using those tokens to fetch multiple parameters. Final output is something like this:
Date Time Old MSISDN New MSISDN Old Profile New Profile CNIC Acc Status Acc Status Migration Channel
(Before) (After)
2019-03-11 | 00:00:14 | 923135260528 | 923029403541 | OMO BVS MA | 0 | 1620221953175 | ACTIVE | | subapp
2019-03-11 | 00:00:14 | 923135260528 | 923003026654 | OMO BVS MA | 0 | 1620221953175 | ACTIVE | | subapp
2019-03-11 | 00:00:14 | 923135260528 | 923003026654 | OMO BVS MA | 0 | 1620221953175 | ACTIVE | | subapp
2019-03-11 | 00:00:14 | 923135260528 | 923038048244 | OMO BVS MA | 0 | 1620221953175 | ACTIVE | | subapp
In the second log instance, these two values are the same. I need to filter those out i.e. I only need to use the non matching values. How do I compare the two non matching values and print the new MSISDN?
Solution 1:[1]
Answer for first version of the question
Try:
awk -F'[*][*]' '/OMO account migration/ && /responseCode":"18"/ && $2 != $4 { print $2}' migration.txt
The avoids the need for spawning multiple processes and connecting them with pipelines. That makes this approach comparatively efficient.
How it works
-F'[*][*]'
This sets the field separator to be two stars. In this way the new MSISDN is field 2 and the old one is field 4.
/OMO account migration/ && /responseCode":"18"/ && $2 != $4 { print $4}
This selects for lines which (1) contain the regex
OMO account migration/
and (2) contain the regexresponseCode":"18"
and (3) have the second field different from the fourth. For any such line, the second field is printed.
Example
Let's consider this three-line test file:
$ cat migration.txt
[2019-03-11 04:15:08 INFO-SUBAPP ESBRestClient:117] ## IP-103.228.158.85##TOKEN-201903110416276787774(**923419606907**)RESPONSE-BODY: {"callStatus":"false","responseCode":"18","description":"OMO account migration – **923481057772**"}
[2019-03-11 04:15:08 INFO-SUBAPP ESBRestClient:117] ## IP-103.228.158.85##TOKEN-201903110416276787774(**923419606888**)RESPONSE-BODY: {"callStatus":"false","responseCode":"19","description":"OMO account migration – **923481057999**"}
[2019-03-11 04:15:08 INFO-SUBAPP ESBRestClient:117] ## IP-103.228.158.85##TOKEN-201903110416276787774(**923419606123**)RESPONSE-BODY: {"callStatus":"false","responseCode":"18","description":"OMO account migration – **923419606123**"}
Let's run our command:
$ awk -F'[*][*]' '/OMO account migration/ && /responseCode":"18"/ && $2 != $4 {print $2}' migration.txt >>newmsisdn.txt
The output file now contains the one new MSISDN that we want:
$ cat newmsisdn.txt
923419606907
Solution 2:[2]
Considering that your actual Input_file is same as shown samples and you need new value for each line, if this is the case then try following.
awk '
/OMO account migration/ && /responseCode":"18"/{
val_old=val_new=""
match($0,/\*\*[0-9]+\*\*/)
val_old=substr($0,RSTART,RLENGTH)
$0=substr($0,RSTART+RLENGTH)
match($0,/\*\*[0-9]+\*\*/)
val_new=substr($0,RSTART,RLENGTH)
}
(val_old!=val_new){
gsub("*","",val_new)
print val_new
}
' Input_file
Explanation: Adding detailed explanation for above code now.
awk ' ##Starting awk program here.
/OMO account migration/ && /responseCode":"18"/{ ##Checking condition if a line contains strings OMO account migration AND responseCode":"18" in it then do following.
val_old=val_new="" ##Nullifying variables val_old and val_new here.
match($0,/\*\*[0-9]+\*\*/) ##Using match OOTB function of awk to match from **digits** here. If match found then value of RSTART and RLENGTH(awk variables) will be SET.
val_old=substr($0,RSTART,RLENGTH) ##Creating variable val_old which is substring of starting point as RSTART and ending point of RLENGTH here.
$0=substr($0,RSTART+RLENGTH) ##Re-defining value of current line with substring whose value starts after matched regexs next index, so that we can catch new value in next further statements.
match($0,/\*\*[0-9]+\*\*/) ##Using match OOTB function of awk to match from **digits** here. If match found then value of RSTART and RLENGTH(awk variables) will be SET(2nd time run).
val_new=substr($0,RSTART,RLENGTH) ##Creating variable named val_new whose value is substring of current line startpoint is RSTART and ending point is RLENGTH here.
} ##Closing BLOCK for string matching condition here.
(val_old!=val_new){ ##Checking condition ig val_old variable is NOT equal to val_new then do following.
gsub("*","",val_new) ##Globaly subsituting * in val_new to get exact value as per OP need.
print val_new ##Printing val_new value here.
}
' Input_file ##Mentioning Input_file name here.
Solution 3:[3]
I'd go for the following approach : I see that every MSISDN number contains twelve digits ([0-9]), located between two double asterisks.
You can find those using following regular expression:
grep -o "\*\*[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\*\*"
In case your system supports this, you might simplify this to:
grep -o "\*\*[0-9]{12}\*\*"
Once you have those, you might use awk
for showing just the ones being different, something like:
'{IF ($1 != $2) PRINT $1 $2}' (not tested).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | Dominique |