1

I have a tab-delimited dataset like:

#1 2      3   4  5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
1 10024 10395 41 K + 2 1 1 12 14  5  0  0  3  1  3  6 2 
1 10679 10795 51 P + 2 1 1 15 14  3  0  0  2  1  2  3 1 

I want to add one more column ($20) to store the values based on column 7-19: if the number in a column is not equal to 0, then plus one. Expected output:

#1 2      3   4  5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 10024 10395 41 K + 2 1 1 12 14  5  0  0  3  1  3  6 2  11
1 10679 10795 51 P + 2 1 1 15 14  3  0  0  2  1  2  3 1  11

How to write the command using awk?

  • how does 11 calculated in your logic? – RomanPerekhrest Aug 3 '17 at 8:29
  • Because in $7-19(total 13 columns) , $13 & &14 are 0, so 11=13-2; just to count the non-zero numbers in 7-19 – MagicPants Aug 3 '17 at 8:33
2

You can iterate over the fields starting from 7-th, check if the value of the field is 0; if not, then keep incrementing 20-th field by 1:

awk -F '\t' 'NR==1 {$(NF+1)=NF+1; print; next}; \
            {for(i=7; i<NF; i++) if ($i != 0) $20++}; 1' OFS='\t' file.txt

For the first record (NR==1), added an extra field header as the last field with adding 1 to the current NF.

0
perl -aF'\t' -lpe '$_ .= "\t" . ($. == 1 ? @F+1 : grep $_, @F[6..$#F])' data.set

Since we need to add another field at the end of line, we use the .= operator on the current record $_. For the special case of the 1st record, we simply append the the expression @F+1, which is interpreted in the scalar context to mean the current number of fields plus 1.

For the non-header records, the expression grep $_, @F[6..$#F] means iterate over the 7th element to the last of the @F array (which is carved out of the record using the tab field separator, specified via the -F'\t' option. In a scalar context, it returns the number of times the condition, in our case, a lone $_, to mean nonzero elements, in the slice 7th...upto last element.


Result

#1 2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20
1  10024 10395 41 K  +  2  1  1  12 14 5  0  0  3  1  3  6  2  11
1  10679 10795 51 P  +  2  1  1  15 14 3  0  0  2  1  2  3  1  11

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.