4
#!/bin/bash

function thous {
    numfmt --g $1 | sed 's/,/./g;s/@//g'
}

aa="1,235"
bb="5,22"
cc=$(echo "$aa + $bb" | bc)

#1
echo $aa
#2
echo $bb
#3
echo $(thous "$cc")
#4
echo "SKIP"

exit

What shown

(standard_in) 1: parse error
(standard_in) 1: parse error
1,235
5,22

What I want

(standard_in) 1: parse error
(standard_in) 1: parse error
1,235
5,22
(some error or nothing at all)
SKIP

If you try to compile this bash shell code, you will got stuck on #3. So, How to tell the terminal, to ignore whatever that cannot be processed and just go on the next process?

Please do tell me if the question is unclear, Thank you

  • It's not clear what that thous is trying to do. Thousand separators and decimal radix characters are locale dependant. What is s/,/./g meant to do? Change the decimal radix from , to .? Change the thousand separator from , to .? Why removing the @s. Where would they come from? – Stéphane Chazelas Mar 31 '22 at 08:34
  • @StéphaneChazelas sorry for late reply, normally when I have thousand separator in my shell script, I usually put export LC_ALL=en_US.UTF-8 export LANG=en_US.UTF-8 on top of the script. I'm using numfmt to format the thousand separator, somehow my bash doesn't accept any other locale other than US, so, in order to change the number from 1,000.00 to my actual local thousand separator which is 1.000,00, that's what the sed does. – CuriousNewbie Mar 31 '22 at 09:05
  • 1
    Swapping , and . would be done with tr ,. .,. – Stéphane Chazelas Mar 31 '22 at 09:33
  • @StéphaneChazelas ah! I learned something useful again, what a useful command. – CuriousNewbie Apr 01 '22 at 01:49

1 Answers1

14

When your script stops, it’s actually numfmt waiting for input — press Ctrld and it will continue.

This happens because numfmt formats its standard input if it’s not given any non-option arguments, and $cc is empty.

A general technique to avoid having numfmt block like this, it to make it read from /dev/null:

numfmt --g $1 < /dev/null | sed 's/,/./g;s/@//g'

See Why is this while loop exiting after the first iteration? for another example where this technique is useful.

However a better approach in your specific case would be to quote your variables; then numfmt will always have an argument, even if $1 is empty:

numfmt --g "$1" | sed 's/,/./g;s/@//g'

You should also avoid option abbreviations in scripts; --g is liable to break if a future version of numfmt introduces another long option starting with “g”. While we’re at it, be sure to separate options from arguments with -- (otherwise numfmt balks at negative values):

numfmt --grouping -- "$1" | sed 's/,/./g;s/@//g'

The script will then run to completion without pause. Once you fix the $cc calculation it will output the expected result; in the mean time, with the "$1" variant you’ll see

numfmt: invalid number: ‘’
Stephen Kitt
  • 434,908
  • Thank you so much for the quick answer, so < /dev/null is the key, I'll note it. is it applicable only on numfmt, or it will also work on another? – CuriousNewbie Mar 31 '22 at 05:59
  • It will work with any command which attempts to read from its standard output (and you don’t want it to). – Stephen Kitt Mar 31 '22 at 06:04
  • @StephenKitt I see that you added more detail to the answer, I'm very appreciate that, I'll keep those method in mind and note it. Thank you – CuriousNewbie Mar 31 '22 at 09:20