3

Please consider below file:

foo,1000,boo,A
foo,1000,boo,B
foo,1001,boo,B
foo,1002,boo,D

And we have below rules:

If $2 equal 1000, $4 should be equal A
If $2 equal 1001, $4 should be equal B
If $2 equal 1002, $4 should be equal C

I want to apply the above rules to a single awk command, where if $4 does not obey, print the record.

The desired output would be:

foo,1000,boo,B
foo,1002,boo,D

I tried with:

awk -F, '{if(($2==1000 && $4!=A) || ($2==1001 && $4!=B) || ($4==1002 && $4!=C)){print $0}}'
  • 1
    what you have tried so far?? – Shravan Yadav Aug 26 '15 at 11:41
  • I Forgot to mention the code I used: awk -F, '{if(($2==1000 && $4!=A) || ($2==1001 && $4!=B) || ($4==1002 && $4!=C)){print $0}}' yet it retrieve nulls. – Eng7 Aug 26 '15 at 11:48
  • ($2==1000 && $4!=A) this means $2 equal to 1000 and $4 NOT equal to A. but your 1st rule states something else – Shravan Yadav Aug 26 '15 at 11:52
  • @ShravanYadav Not something else, what I need to get is the records that do not match that rule, and that what was mentioned in the question. – Eng7 Aug 26 '15 at 11:55
  • 1
    Why didn't you just fix your first version of this question?  Why did you delete it and reask it?  (Google has cached the first version of the question here.) – Scott Aug 26 '15 at 17:38
5

Use this:

awk -F, '($2==1000 && $4!="A") || ($2==1001 && $4!="B") || ($2==1002 && $4!="C")' file

In the curvy brachets are the 3 conditions; if one of them applies the line will be printed. The conditions inside the brackets are connected with a AND, so both must apply.

  • I tried this code before, yet it retrieve nulls – Eng7 Aug 26 '15 at 11:53
  • @Azizieh7 what is your awk version? – chaos Aug 26 '15 at 11:56
  • 1
    @Azizieh7 A means variable A, and "A" means string A – Archemar Aug 26 '15 at 12:01
  • @chaos GNU Awk 3.1.7 – Eng7 Aug 26 '15 at 12:01
  • @Azizieh7 I tested with gawk 3.1.8 and mawk 1.3.3: both worked. Have you copied the exact command from my answer? – chaos Aug 26 '15 at 12:02
3

The long|many terms better put into array:

awk -F, 'BEGIN{a[1000]="A";a[1001]="B";a[1002]="C"}$4!=a[$2]' file
2

You can do that with egrep:

egrep -v '.*,((1000,.*,A)|(1001,.*,B)|(1002,.*,C))' filename

Will match all lines that don't have 2nd column with 1000 and 4th with A, 2nd with 1001 and 4th with B or 2nd with 1002 and 3rd with C.

1

use grep

grep -v '.1000.*.A\|.1001.*.B\|.1002.*.C' input filename

and your awk will be corrected as below

 awk -F, '{if(($2==1000 && $4!="A") || ($2==1001 && $4!="B") || ($2==1002 && $4!="C"))print $0}' inputfilename
  • The grep version doesn't adequately identify the fields. eg it should (but doesn't) output lines such as: foo,21000,boo,A, foo,1000,boo,ZA, foo,1000,boA,C – Peter.O Aug 26 '15 at 13:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.