I have a tab-delimited text file containing C1...Cn columns and R1 to Rn rows. Column 10 (C10) has a field 'X'=four comma separated integer values (X=a,b,c,d). I would like do a small arithmetic operation on C10, such as (a/(a+b+c+d))*100 and put the results as new Column (Cn+1) by appending the same file OR in a new out file.

(1) Can anybody help me with a unix shell script to do it for a single file?

(2) If I want loop over the same calculations over multiple files, can you help me with a shell wrapper?


Use awk method

awk -F'\t' '{ A=$10;gsub(/X=/,"",A); split(A,B,","); print $0"\t"(B[1]/(B[1]+B[2]+B[3]+B[4]))*100 }' input.txt > output.txt
  • Thanks. Seems awk rocks. However, within some of the columns in my input file, there are multiple nested fields with an identifier and then separated by semicolon. For example C1...C10...Cn # columns with column name C1 to Cn For eg., in C10, there are multiple fields in each row separated by semicolons. eg.: DP=x,y,z,; DP4=a,b,c,d,; etc. Task: From inputfile.txt, choose Column C10, choose field DP4 and perform arithmetic opertaion (c+d)/(a+b+c+d) -> paste as new column Cn+1 in the original tab delimited file. – panbar Mar 12 '16 at 21:12
  • Two Solutions here: awk -F'\t' '{ Z=$10; split(Z,A,";"); for (I in A) { if(A[I]~/DP4/) { gsub(/DP4=/,"",A[I]);split(A[I],B,","); } } print $0"\t"((B[3]+B[4])/(B[1]+B[2]+B[3]+B[4]))*100; }' input.txt and the second solution for the same is: awk -F'\t' '{ Z=$10; gsub(/.*DP4=/,"",Z); gsub(/;.*/,"",Z); split(Z,B,","); print $0"\t"((B[3]+B[4])/(B[1]+B[2]+B[3]+B[4]))*100; }' input.txt – sureshraju Mar 13 '16 at 16:58
  • does this solve your issue? – sureshraju Mar 14 '16 at 20:09

Perl to the rescue!

perl -nlaF '\t' -e ' my ($A, $B, $C, $D) = split /,/, $F[9];
                     print "$_\t", 100*$A/($A+$B+$C+$D);
                   ' input-file > output-file
  • -n reads the input line by line
  • -l handles the newlines in print.
  • -a splits input on what -F specifies
  • $_ contains the line read from the input
  • Sorry, the column C10 contains a field identifier X=a,b,c,d – panbar Mar 11 '16 at 18:39
  • @panbar: You can remove it by $A =~ s/.*=//. – choroba Mar 11 '16 at 22:16

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.