I'm struggling to adapt a script, which loops through a large number of individual files (subj_id), and prints out the value of $4 in a specified line.

Text file contains lines

# Measure Brain, ICV, Brain Volume, 1118718.609121, mm^3

My script contains this line to export the number 1118718:

printf "%g," `cat ${subj_id}/stats/aseg.stats | grep ICV | awk -F, '{print $4}'` > BrainVol.csv

My values are either A) 666666.012345 or B) 7777777.012345, so the script runs fine with A) and exports 666666 but for case B) it exports 7777780. I gather I need use printf to specify number of decimals for output but '{printf "%.2f\n",$4}' doesn't work.

Sorry this is too basic but what's the correct order in this pipe to include a decimal specifier (if that's the problem).

It's a bash script and I'm running Mac OS X 10.7.5

Any help would be greatly appreciated.

  • What about that printf doesn't work? – Eric Renouf Dec 23 '15 at 17:38
  • I used printf "%g," cat ${subj_id}/stats/aseg.stats | grep Brain | awk -F, '{printf "%.2f\n",$4} > BrainVol.csv which still gives output in scientific notation 1.21079e+06 if it's a 7777777.012345 number. Am I using it in the wrong place in the pipe, given that the entire line starts with printf? – julia Dec 23 '15 at 17:41

The following works for me:

awk -F, '/ICV/ {printf "%.2f\n", $4}' ${subj_id}/stats/aseg.stats

where if I use the following source:

# Measure Brain, ICV, Brain Volume, 1118718.609121, mm^3
# Measure Brain, ICV, Brain Volume, 7777777.012345, mm^3
# Measure Brain, ICV, Brain Volume, 666666.012345, mm^3

I get the following output:


As @glennjackman noted, we can make the match more specific by checking if the expected field is the exact string we want instead of matching a pattern anywhere in the line by doing

awk -F, '$2 == " ICV" {printf "%.2f\n", $4}' ${subj_id}/stats/aseg.stats

or if we want to be flexible about spaces we could match the pattern against only that field

awk -F, '$2 == /^[[:space:]]*ICV[[:space:]]*$/ {printf "%.2f\n", $4}' ${subj_id}/stats/aseg.stats
  • Thank you, Eric! That outputs 777777.01 correctly. One follow-up question. In the example I gave "ICV" is intentionally a unique string. But my inputs contain the word Brain so /BrainTotal/ is no longer unique. How do I modify the search to search for exact string, not any word that appears in string? – julia Dec 23 '15 at 17:48
  • 2
    @julia I would do awk -F, '$2 == " ICV" {... – glenn jackman Dec 23 '15 at 18:09

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.