2

I need to delete all lines in a file, if the values in all the columns are 0 (so if the sum of the row is 0).

My file is like this (13 columns and 60000 rows, tab delimited)

KO  gene    S10 S11 S12 S1  S2  S3  S4  S5  S6  S7  S8  S9
K02946  aap:NT05HA_2163 0   0   0   0   1   0   8   0   0   5   0   0
K06215  aar:Acear_1499  0   0   0   0   0   0   8   0   0   0   0   0
K00059  acd:AOLE_11635  0   0   5   0   0   0   0   0   8   0   0   0
K00991  afn:Acfer_0744  0   0   0   0   0   0   0   0   0   0   0   0
K01784  aha:AHA_2893    0   0   0   0   0   0   7   0   0   0   0   0
K01497  amd:AMED_3340   0   0   0   0   0   0   0   0   0   0   0   0

How can I do?

  • grep -v '0 0 0 0 0 0 0 0 0 0 0 0$' (tabs in between). – Stéphane Chazelas Nov 29 '14 at 20:04
  • @StéphaneChazelas: You mean grep -v? – cuonglm Nov 29 '14 at 20:06
  • @Costas, ITYM grep -vE '( 0){12}$' (TAB before 0) – Stéphane Chazelas Nov 29 '14 at 22:18
  • @StéphaneChazelas yes, your solution is cool, it looks great. (sorry I forgot brackets and have wrong counting of zeros: there are 11 only) – Costas Nov 29 '14 at 22:33
3

If you'd like awk solution:

awk '{s=0; for (i=3;i<=NF;i++) s+=$i; if (s!=0)print}' infile > outfile

If you like to remain first line as header start script from the second:

awk 'NR > 1{s=0; for (i=3;i<=NF;i++) s+=$i; if (s!=0)print}' infile > outfile
3

If your columns contain only non-negative number, you only have to print line have at least one field with number greater than 0.

With perl:

$ perl -MList::Util=first -anle '
  print if first {$_ > 0} @F or $. == 1;
' file
KO  gene    S10 S11 S12 S1  S2  S3  S4  S5  S6  S7  S8  S9
K02946  aap:NT05HA_2163 0   0   0   0   1   0   8   0   0   5   0   0
K06215  aar:Acear_1499  0   0   0   0   0   0   8   0   0   0   0   0
K00059  acd:AOLE_11635  0   0   5   0   0   0   0   0   8   0   0   0
K01784  aha:AHA_2893    0   0   0   0   0   0   7   0   0   0   0   0

You should read this question for security reason if using perl solution.

With awk:

$ awk 'FNR == 1{print;next}{for(i=3;i<=NF;i++) if($i > 0){print;next}}' file
  • This is a pretty good insight, I think. I think it would work with grep like: grep '\t[1-9]'. It's probably better to use a literal tab there, but it's much harder to represent in a comment. – mikeserv Nov 30 '14 at 4:06

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.