0

I'm currently staring at a problem in my shell script involving awk.

My goal is to add the sum of a column of a csv file into a custom command prompt (PS1). What I currently have is the following.

  colToUse=$(awk -F ';' -v var="$1" 'FNR==1 {for(counter=1; counter<= NF; counter++){ if($counter == var) break;}} END{print counter}' data.csv)
  check=$(awk -F ';' 'END{ print NF }' data.csv)
  if [[ $colToUse -eq check+1 ]]
  then
    colToUse=`expr $colToUse - 1`
  fi
  var=$(awk -F ';' -v loc="$colToUse" '{s+=$loc} END{print s}' data.csv)
  echo $var

Now this works fine; the first awk iterates over the rows to find the header which matches with $1, the second solves a problem where it overshoots the final header for some reason, and the third awk then calculates the sum of all the values in the column of the selected header.

My problem is that the value produced will be static - When inserted into PS1, it will remain the same number. What I'm looking for is a way to escape the awk, so that I can put it into the PS1, and make it recalculate the sum whenever a command is inserted into the prompt. How would I go about doing this?

Er098
  • 15
  • 3
  • 1
    Show us how you're assigning the result to PS1. *That's* your problem, nothing to do with the code you show us (or with awk, specifically, at all). – Charles Duffy Jun 19 '20 at 13:46
  • ...well, rather than wait for that edit, I linked directly to another question caused by the same problem. Short from: Instead of `PS1="$(yourfunc)"\$`, use `PS1='$(yourfunc)$'` -- single quotes so the command substitution is stored in the string, not executed on assignment. – Charles Duffy Jun 19 '20 at 13:48
  • BTW, ```colToUse=`expr $colToUse - 1` ``` is very slow to run, because `expr` is not built into the shell. All shells compatible with the 1992 POSIX.2 standard support `colToUse=$((colToUse - 1))`, which is much faster. – Charles Duffy Jun 19 '20 at 13:49
  • That said, if you want to call this every single time you render your prompt, I *strongly* advise that you get it down to only run `awk` once -- it's a powerful enough language that you can do the work of all four of your awk calls (and the connecting bash logic) in just one program. Subprocesses are expensive; their use should be minimized. – Charles Duffy Jun 19 '20 at 13:50
  • What I was doing was calling the code I gave above as a function, then echoing the result of this function (the var) to another variable, which would then be placed into the PS1. Anyway, while experimenting with this myself, I stumbled onto the answer by accident - all I had to do was wrap the call to that function in an escape (echo "\$(func_name)"). Thanks for the help, though! – Er098 Jun 19 '20 at 15:43
  • Yes, using the escape does the same thing as switching to single quotes; both prevent the command substitution from being expanded before prompt rendering time. – Charles Duffy Jun 19 '20 at 20:25
  • ... If you'd showed us how you were embedding the content in the prompt, it might have been also possible to point out the need for a function -- but we can't identify problems with code that isn't included in the question; we didn't know that you _weren't_ doing so already. – Charles Duffy Jun 19 '20 at 20:27

0 Answers0