0

I have a file like below

1,1230,add
1,1235,remove
2,1240,add
2,1245,remove
3,1250,add
4,1255,remove

I want to print those lines which have a unique value for the first field, and where the 3rd field is equal to add. The expected output for the example would be

3,1250,add

or only the first column, i.e.

3

The below command give me distinct records, but later I want to check if 3rd column is "add" then only print the output.

awk -F ',' 'print $1' filename | uniq -u
0
1

In this case, a double-pass approach comes to mind:

awk -F',' 'NR==FNR{seen[$1]++;next} $3=="add" && seen[$1]==1' file.txt file.txt

This will process the input file twice (hence it is stated two times as argument).

  • In the first pass, where NR , the global line counter, is equal to FNR, the per-file line-counter, we only count how often this particular value of the first field is encountered, but otherwise skip processing immediately (the next statement).
  • In the second pass, we check if the third field equals add, and that the first field has only occured once. If so, we print the line (because these two conditions will evaluate to true).
0

Since AdminBee already showed the awk-way, here's another approach with standard utils:

 sort -t',' -k1,1 file | uniq -u -w 1 | grep 'add$'
  • sort using comma as separator and sorting by field 1 only
  • uniq printing only unique lines but checking no more than 1 (!) character per line
  • now grep lines ending in "add"

Limitation: uniq of course only checks one character. For two- or more-digit entries in field 1, one would have to preprocess field 1 e.g. with zero-padding on the left and then increase the number of characters for the check accordingly. Sorting may be skipped if your file is already sorted as given in your example.

2
  • @ricky Distinct? So you want lines where the first field is unique (i.e. appears only once) in the file and last field is add?
    – FelixJN
    Jan 19 at 15:28
  • @Fiximan, Correct
    – ricky
    Jan 19 at 15:29
0

in one go with awk :

awk -F ',' '  
  { if ( ! seen[$1]++ )
    { if ( $3 == "add" )
        keep[$1] = $0
    }
    else
    {
      if ( keep[$1] )
        delete keep[$1]
    }
  }
  END  {
    for (i in keep)
      print keep[i]
  }'  infile

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.