bashawk

Dynamic precision in awk printf using shell variable


I think this is simple, but it's not working for me. This is what I have.

float=$(awk -v res="$result" 'BEGIN {printf "%.2f", res / 1000}')

I want to use a variable to set the decimal value for %.2f but awk will have none of it. This is what I need.

var=2
float=$(awk -v res="$result" 'BEGIN {printf "%.${var}f", res / 1000}')

I hope someone can show me the error of my ways.


Solution

  • It happens because $var are not substituted between simple quotes ' If you want $var to be substituted by its value, 'BEGIN...' should be "BEGIN..." so that var is replaced.

    But then, since you need actual double quotes " inside that BEGIN expression, you need to escape them

    So

    float=$(awk -v res="$result" "BEGIN {printf \"%.${var}f\", res / 1000}")
    

    is probably what you were trying to do. Only difference with your attempt are the 2 I've described (use " to enclose expression. And then, escaping the \" around %.${var}f

    It is better to avoid injection of bash variable or expression in the awk code, and deal with var as you already dealt with res/result.

    I answered to your question "why it happens, were is the bug", and it happens because of the ' that prevented your $var injection (not mine :D) to work as you intended. So, I've shown that. And I usually try to keep as close as possible to initial code (otherwise, I could have solved your problem using totally different technique, and even skipping awk; that would solve your problem, but not answer your question)

    Yet, I agree that this answer your "why" question, but is not the best solution to your problem.