Nands
Nands

Reputation: 67

subtracting the minimum value in a file with shell script

I need some help with shell script.

I have the following text file (open_calculator[1]):

value:0,0236679
value:0,0272904
value:0,0282416
value:0,0295671
value:0,0318641
value:0,032451
value:0,0333313
value:0,0360229
value:0,0364378

And I need to get the minimum value of this file and subtract it of the other values of the same text file. So my output should be:

value:0,0000000
value:0,0036225
value:0,0045737
.
.
.
value:0,0127699

In order to achieve this, I wrote this script:

file="open_calculator[1]"

min= cut -f2 -d ":" $file | sort -n | head -1
number=$(grep -o '[0-9],[0-9]*' $file)
resul=$((10#$number - 10#$min))

sed -i 's/value:$number/valor:$resul/' $file

but when I run this code, I get this message error:

line 6:10#0,0236679: value too great for base (error token is "0236679")

Someone could help me with this script? Sorry for my bad English, it's my first time writing here.

Thanks in advance!

Upvotes: 2

Views: 215

Answers (2)

Rahul Verma
Rahul Verma

Reputation: 3089

You can modify your code as following:

tr ',' '.' <open_calculator[1] > file  #Converting each , to . to make these numbers decimal

min=`cut -f2 -d ":" file | sort -n | head -1` 

awk -F":" -v m=$min '{print $1":"($2-m) } ' file | tr "." ","

Output:

value:0
value:0,0036225
value:0,0045737
value:0,0058992
value:0,0081962
value:0,0087831
value:0,0096634
value:0,012355
value:0,0127699

Solution 2 : One liner using awk and tr only

tr "," "." <open_calculator[1] | awk -F":" 'NR==1{a[NR]=min=$2} {a[NR]=$2; a[NR]<min?min=a[NR]:min; } END{for(i=1;i<NR;i++){print "value:"a[i]-min}}' | tr "." ","

Here we are finding min in awk itself and subtracting from second column. The result from awk is piped to tr to translate "." to "," to match your desired output.

Upvotes: 2

choroba
choroba

Reputation: 241988

bash doesn't handle floating point arithmetics.

Perl to the rescue:

perl -e 'while (<>) {
             s/,/./;
             ($n) = /([0-9.]+)/;
             $min = $n unless defined $min && $min < $n;
         }
         open ARGV, $ARGV;
         while (<>) {
             s/,/./;
             s/([0-9.]+)/$1 - $min/e;
             s/\./,/;
             print;
         }' -- filename

The first loop finds the minimum, then open reopens the file again and the second loop subtracts the minimum. The substitutions are needed as Perl uses decimal dot, not comma.

Upvotes: 0

Related Questions