2017-08-31 3 views
2

Ich brauche etwas Hilfe mit Shell-Skript.Subtrahieren Sie den Mindestwert in einer Datei mit Shell-Skript

Ich habe die folgende Textdatei (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

Und ich brauche den Minimalwert dieser Datei zu erhalten und es von den anderen Werten derselben Textdatei subtrahieren. So sollte mein ausgegeben:

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

Um dies zu erreichen, schrieb ich dieses Skript:

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 

aber wenn ich diesen Code ausführen, bekomme ich diese Fehlermeldung:

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

Jemand könnte mir mit diesem Skript helfen? Sorry für mein schlechtes Englisch, es ist mein erstes Schreiben hier.

Vielen Dank im Voraus!

+0

Bezeichnen diese Werte Gleitkommazahlen/Dezimalzahlen? – batMan

+0

Ja, diese Werte sind Dezimalzahlen. – Nands

Antwort

1

Sie können den Code wie folgt ändern:

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 "." "," 

Ausgang:

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

Lösung 2: One-Liner mit awk und tr nur

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 "." "," 

Hier finden wir min in awk selbst und subtrahieren von der zweiten Spalte. Das Ergebnis von awk wird an tr übergeben, um "." zu "," um die gewünschte Ausgabe zu erreichen.

+0

Die gewünschte Ausgabe ist Doppelpunkt getrennt und verwendet ein Komma als Dezimalpunkt. –

+0

@BenjaminW .: vielen Dank für Ihre Hinweise. Lassen Sie mich beheben – batMan

+1

Vielen Dank BatMan. Die zweite Lösung funktioniert gut, aber wie kann ich die Ausgabe in der Datei speichern? – Nands

0

Bash behandelt keine Fließkomma-Arithmetik.

Perl zur Rettung:

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 

Die erste Schleife findet das Minimum, dann wieder öffnet open die Datei wieder, und die zweite Schleife subtrahiert das Minimum. Die Ersetzungen werden benötigt, da Perl Dezimalpunkte und kein Komma verwendet.

+0

Danke, ich kannte Perl nicht, aber jetzt werde ich anfangen zu studieren. – Nands

Verwandte Themen