2012-03-31 2 views
1

Ich habe die folgende TextdateiBash-Skript für die Analyse und Verarbeitung bestimmter Zeilen einer Textdatei

40 timesteps took 58.320842 seconds 
greetings 0 
80 timesteps took 58.048400 seconds 
greetings 0 
120 timesteps took 59.459687 seconds 
greetings 0 

Was würde Ich mag nur die Linien tun analysiert die Sekunden enthalten, füge sie zusammen und aus dem Druck Endergebnis.

Wie kann ich das tun?

Vielen Dank im Voraus.

+0

Ich weiß nicht viel Bash ...! Alles, was ich weiß, ist, dass ich einige reguläre Ausdrücke mit sed verwenden muss. Aber ich habe keine Ahnung wie ... – kstratis

Antwort

2

awk ist für diese Art der Verarbeitung gut geeignet.

Um die Gleitkomma-Genauigkeit zu verarbeiten, können Sie printf mit einer Format-Zeichenfolge für jede Variable verwenden.

Es gibt auch eine andere Art und Weise, die das Format-String für alleausgewertet Variablen setzt. Die Formatierung wird bei Auswertungen angewendet (die intern sprintf verwenden. Die Steuerung integrierte Variable OFMT ist. Built-in Variables That Control awk See.

#!/bin/bash 
file="$1" # $1 is the 1st command line parameter 
awk -vOFMT="%.6f" '/ took /{ secs+=$4 } END{ print secs }' "$file" 

Mit sed mehr beteiligt ist, weil es keine Berechnungen tun und sogar bash selbst kann das nicht Gleitpunktarithmetik, so dass Sie so etwas wie awk oder bc in jedem Fall verwenden müssen

Wenn Sie wirklich sed verwenden möchten.

#!/bin/bash 
file="$1" # $1 is the 1st command line parameter 
{ sed -nr 's/.* took ([0-9.]+).*/\1+/p' "$file" |tr -d '\n'; echo 0; } |bc 
+0

Ich habe Kraftans Lösung benutzt, aber deine Erklärung besser gefallen! Danke! – kstratis

1

Sie können einen einfachen Shell-Befehl verwenden:

grep timesteps <file-name> | awk '{x += $4} END{printf("%.5f", x)}' 

Ändern Sie die Nummer in der printf Anweisung, um Ihre bevorzugte Ausgangspräzision.

+0

Ausgezeichnet! Kannst du mir auch sagen wie ich den als Parameter geben kann? – kstratis

+0

Ich bin froh, ich könnte helfen. Entschuldigung, ich habe deinen Kommentar zu spät gesehen ... – kraftan

1

Die awk-Lösungen sind gute Antworten. Für Spaß, hier ist eine Ruby-Antwort ...

ruby -e 'puts readlines.inject(0) { |m, v| m += v.split[3].to_f }' < file 

... oder vielleicht ...

ruby -e 'puts readlines.map { |x| x.split[3].to_f }.reduce(&:+)' < file 

... die Datei als Parameter an ein Skript übergeben ...

#!/usr/bin/ruby 
puts $<.map { |x| x.split[3].to_f }.reduce(&:+) 
Verwandte Themen