Home > Back-end >  Bash parameter expansion from both sides
Bash parameter expansion from both sides

Time:07-05

I'm getting dollar values from a file into the variable in the form p=$1234.56, and would like remove $ and decimal places to get integer value in my conditional like

if [[ ${p%%.*} < 1000]]; then p=${p}0; fi

But this doesn't remove the $ sign, and I don't want to do it in 2 steps and modify actual variable, as I need $ for later use. How to get integer value regardless of number of digits ie ($2.2, $123456.1234...)?

CodePudding user response:

Unfortunately, there is no way to avoid performing multiple parameter expansions if you need to remove multiple patterns, in the general case.

In simple cases like this, you can avoid a temporary variable just by assigning back to the same variable.

p=${p#\$}
p=${p%.??}

In your specific scenario, of course, you can just replace any nonnumeric characters globally, and accept that the number will be multiplied by 100. You will obviously then need to multiply the number you compare against correspondingly.

if [[ ${p//[!0-9]/} < 100000 ]]

Of course, for this to work, you need to be sure that your variable's value conforms to your expectations. If the value could have different numbers of decimal places depending on what a user passes in or where you read the input from, you need to perform additional normalizations, or just use a different approach entirely (frequently you'd pass your input to Awk or bc which support floating point math, unlike the shell).

However, the string substitution parameter expansion ${variable//pattern/replacement} is a Bash extension, and not portable to Bourne/POSIX sh.

CodePudding user response:

It's not possible without modifying the var. But you can use a subshell process with something like sed

if [[ $(sed 's/\$\([0-9]*\)\..*/\1/' <<< $p) < 1000 ]]; then p=${p}0; fi
  • Related