0

I need to count the values in 2nd column from the output of some command. However, the challenge is I need to consider only those lines which comes after a line containing specific patter. For example:
output of a command (ptree) -


1234 /bin/user/puc/loc
   3342 /bin/user/123/loc
      7783 sup
         1234 abc AAA1 BBB1 CCC1 D444
         0909 abc xx11 sd11 lk23 3484
         8383 cur uh9u 38tt kj33 sd99
         3030 zzz qq11 11ii 39ii ij33
         0101 sup kk88 sis8 88si mm92
         1020 zz0 98df cv99 kids 8dhd
         1111 sup 9ike 39ei 93je 39de

I need to find the first occurrence of sup (which is in 3rd line) and want to have a count of all the values(grouping the similar values) in 2nd column(bold marked) after 3rd line. The number of lines before the first occurrence of 'sup' is not fixed, it may vary from time to time(so can not hard code it to 3).

The output should be like this -

abc 2  
cur 1  
zzz 1  
sup 2  
zz0 1  

Can someone suggest the optimal way to do this?

1

Try this,

 sed -e '1,/sup/d;/^[0-9]/,$d' file.txt | awk 'NF>=3{ a[$2]++ } END { for (n in a) print n, a[n] }'
  • 1,/sup/d will remove all before sup
  • /^[0-9]/,$d will remove if anyother process trailing sup
  • Thanks for a quick reply. But as I said, I can not hard code 3. There may be more or less number of lines before the first occurrence of 'sup' – Suraj Jan 21 at 12:23
  • @Suraj please clarify if there could be any lines like 1234 abc AAA1 BBB1 CCC1 D444 before the line containing sup? – Prvt_Yadv Jan 21 at 12:25
  • @P_Yadav yes there can be lines like you mentioned before the line containing sup.. and we need to ignore them – Suraj Jan 21 at 12:30
  • @msp9011 This is the exact input. I just replaced the actual values with the dummy values. to be more specific the lines that appear before first 'sup' (i.e. 1st and 2nd line in this case) are not bound to have only 2 fields they can have more fields as well – Suraj Jan 21 at 12:45
  • Thanks @msp9011 its working ! – Suraj Jan 21 at 15:03
0

You can set a "processing switch" the first time a record matches sup, and only count if the switch is set:

$ gawk '
    /sup/ {p=1} 
    p {a[$2]++} 
    END {
      PROCINFO["sorted_in"] = "@ind_str_asc"; 
      for (i in a) print i, a[i]
    }' file
abc 2
cur 1
sup 3
zz0 1
zzz 1

If your Awk doesn't support the PROCINFO array traversal feature, you can pipe the output through an external sort

  • Thank you very much ! It's working and its easy to understand :) Just one thing, can we update it to exclude first occurrence of sup so that in the output it says sup 2 – Suraj Jan 21 at 15:10
  • @Suraj if I understand you correctly, try changing the first action to /sup/ {p++} and the second rule to p > 1 – steeldriver Jan 21 at 15:12
0

Very similar to @msp9011

$ sed -n '/sup/,$p' input.txt|awk 'NR>1 {counts[$2]++} END  { for(key in counts) print key, counts[key] }'

sed prints all lines from the first line containing sup until the end of the file. awk counts from the second line that is passed to it, all different values in the second column. At the end it prints out the result.

EDIT: As @msp9011 mention this assumes that there are no more processes after it. To find this process somehwere between here is an updated version:

$ sed -n '/sup$/,/^[0-9]/p' count.txt|sed -e '1d' -e '$d'|awk '{counts[$2]++} END  { for(key in counts) print key, counts[key] }'

sed prints everything from the line that ends with sup until a line starting with a number. Then the first and last line are removed and awk starts counting.

EDIT2: @msp9011 already updated their answer :)

  • I thought the same, but we can't be sure that sup will be the last process of ptree – msp9011 Jan 21 at 13:12

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.