Bearbeiten Sie Werte in einer txt-Datei mit dem Befehl sed / awk / grep

9

Seit 5 Jahren benutze ich eine Wetterstation La Crosse WS2350. Die von der Wetterstation bereitgestellten Daten werden mit open2300 auf RPI verarbeitet. Das funktioniert sehr gut. Die Temperaturdaten sind jedoch falsch (Sensor). Die Temperaturdaten sind 1 ° C niedriger.

Da ich den Sensor nicht kalibrieren kann, möchte ich den Temperaturwert aus der von der Wetterstation extrahierten Datei ändern.

Diese Textdatei (current.txt) enthält:

Date 2016-Dec-03
Time 10:30:29
Ti 11.9
Timin 11.6
Timax 27.7
TTin 10:34
DTimin 2016-01-19
TTimax 00:44
DTimax 2016-08-28
To -2.4
Tomin -4.8
Tomax 37.4
TTomin 06:46
DTomin 2016-02-18
TTomax 16:13
DTomax 2016-07-19
...

Ich möchte +1 zu den Werten "To", "Tomin", "Tomax" hinzufügen und die Textdatei mit den richtigen Werten überschreiben.

Nachdem ich mir die Befehle sed und awk angesehen habe, stelle ich fest, dass ich veraltet bin. Kann mich jemand führen? Vielen Dank

Bearbeiten:

Ich habe eine andere Datei vergessen: ws2308.log Alle 15 Minuten wird der Datei ws2308.log eine neue Zeile hinzugefügt:

...
20161203150600 2016-Dec-03 15:06:00 11.8 -1.1 -3.2 65 87 0.0 157.5 SSE -1.1 569.80 1015.700 
20161203152100 2016-Dec-03 15:21:00 12.3 -1.1 -3.2 64 87 0.0 157.5 SSE -1.1 569.80 1015.600 
20161203153600 2016-Dec-03 15:36:00 12.2 -1.2 -3.3 64 87 0.0 135.0 SE -1.2 569.80 1015.700 

Der zu ändernde Wert ist das 5. Feld (das erste -1,2).

Es ist auch erforderlich, dass in der letzten Zeile der Wert der Temperatur um 1 erhöht wird und die letzte Zeile mit dem richtigen Wert überschrieben wird. Nur die letzte Zeile wird vom Programm PHP berücksichtigt, wodurch die Ergebnisse in einem Diagramm angezeigt werden können.

Vielen Dank

Ookpik
quelle

Antworten:

12

Hier ist eine etwas idiomatischere AWK-Variante current.txt( Steves zweite Antwort ist noch idiomatischer!):

awk '/^To(|min|max) / { print $1, $2 + 1; next } 1' current.txt

Dies sucht nach Zeilen, die mit To, gefolgt von nichts minoder maxgefolgt von einem Leerzeichen beginnen. Für übereinstimmende Zeilen werden das erste Feld und das zweite Feld inkrementiert gedruckt, getrennt durch das Standard-Ausgabefeldtrennzeichen (Leerzeichen). Dann springt es zur nächsten Zeile. Alle anderen Zeilen werden unverändert gedruckt ( 1ist eine Abkürzung in AWK).

Beachten Sie, dass das Überschreiben der Datei mit den neuen Werten wahrscheinlich keine gute Idee ist: Sie wissen nicht, ob die Werte korrigiert wurden oder nicht ... Wenn Sie die Datei jedes Mal vom Gerät abrufen, gilt dies nicht.

Die gleiche Überlegung gilt für ws2308.log, also lassen Sie es uns jedes Mal in seiner Gesamtheit verarbeiten:

$ awk 'NF >= 5 { $5 = $5 + 1 } 1' ws2308.log
20161203150600 2016-Dec-03 15:06:00 11.8 -0.1 -3.2 65 87 0.0 157.5 SSE -1.1 569.80 1015.700
20161203152100 2016-Dec-03 15:21:00 12.3 -0.1 -3.2 64 87 0.0 157.5 SSE -1.1 569.80 1015.600
20161203153600 2016-Dec-03 15:36:00 12.2 -0.2 -3.3 64 87 0.0 135.0 SE -1.2 569.80 1015.700

Wenn Sie nur die letzte Zeile möchten:

$ awk 'NF >= 5 { $5 = $5 + 1; lastline = $0 } END { print lastline }' ws2308.log
20161203153600 2016-Dec-03 15:36:00 12.2 -0.2 -3.3 64 87 0.0 135.0 SE -1.2 569.80 1015.700

oder wenn Sie möchten, dass die Datei nur mit der letzten Zeile geändert wird :

$ awk 'length(prevline) > 0 { print prevline } NF >= 5 { prevline = $0; $5 = $5 + 1; lastline = $0 } END { print lastline }' ws2308.log
20161203150600 2016-Dec-03 15:06:00 11.8 -1.1 -3.2 65 87 0.0 157.5 SSE -1.1 569.80 1015.700 
20161203152100 2016-Dec-03 15:21:00 12.3 -1.1 -3.2 64 87 0.0 157.5 SSE -1.1 569.80 1015.600 
20161203153600 2016-Dec-03 15:36:00 12.2 -0.2 -3.3 64 87 0.0 135.0 SE -1.2 569.80 1015.700
Stephen Kitt
quelle
10

Hier ist eine Lösung. Für alle Zeilen, die mit "An", "Tomin" oder "Tomax" gefolgt von einem Leerzeichen beginnen, drucken Sie das erste Feld und dann das zweite Feld, das um 1 erhöht wird. Andernfalls drucken Sie einfach die vollständige Zeile.

$ awk '{if(/^(To|Tomin|Tomax) /){print $1 " " $2+1}else{print $0}}' w.txt
Date 2016-Dec-03
Time 10:30:29
Ti 11.9
Timin 11.6
Timax 27.7
TTin 10:34
DTimin 2016-01-19
TTimax 00:44
DTimax 2016-08-28
To -1.4
Tomin -3.8
Tomax 38.4
TTomin 06:46
DTomin 2016-02-18
TTomax 16:13
DTomax 2016-07-19
$
Steve
quelle
5

Ein anderer Ansatz, leicht golfen .

$ awk '/^To/{$2++}1' w.txt
Date 2016-Dec-03
Time 10:30:29
Ti 11.9
Timin 11.6
Timax 27.7
TTin 10:34
DTimin 2016-01-19
TTimax 00:44
DTimax 2016-08-28
To -1.4
Tomin -3.8
Tomax 38.4
TTomin 06:46
DTomin 2016-02-18
TTomax 16:13
DTomax 2016-07-19
$
Steve
quelle
3
Schön (also +1), aber Sie hätten das einfach als Bearbeitung zu Ihrer vorhandenen Antwort hinzufügen können!
Stephen Kitt
@ Scott -iauf awkeine Include - Datei hinzufügt, es ist nichts , wie sed‚s - -iOption.
Stephen Kitt
@ StephenKitt: D'oh! Ich wusste, dass.
Scott
5

Ein Perl-Ansatz:

perl -i -ape '/^To/ && s/$F[1]/$F[1]+1/e' file

Das -imacht es die ursprüngliche Datei überschreiben, so dass er nichts auszudrucken, wird es die Datei direkt ändern.

Die -aMarken verhalten sich perlso awk, als würden sie ihre Eingabe auf Whitesapce (oder irgendetwas anderem von -F) in das Array aufteilen @F. Das zweite Feld ist also, $F[1]weil Arrays bei 0 zu zählen beginnen. Das Skript ersetzt daher das zweite Feld durch sich selbst, das in Zeilen, die mit beginnen, um eins erhöht wird To.

terdon
quelle
2

Dies wird die Arbeit erledigen:

  1. Zuerst werden alle Zeilen durchlaufen
  2. Überprüfen Sie dann das erste Element und prüfen Sie, ob es Ihren Wünschen entspricht.
  3. Wenn es übereinstimmt, drucken Sie es aus und fügen Sie +1 zum nächsten Element in der Zeile hinzu
  4. Andernfalls drucken Sie es einfach aus und drucken Sie den nächsten Artikel

    awk '{
        for(i=1;i<=NF;i++) {
                t+=$i;if(i==1){
                        if($i=="To" ||$i=="Tomin" ||$i=="Tomax"  ){
                                printf  "%s ",$i;
                                print $(i+1)+1;}
    
                        else{
                                print $0
                                }
                        }
                        };
        }' current.txt
    

AUSGABE

Date 2016-Dec-03
Time 10:30:29
Ti 11.9
Timin 11.6
Timax 27.7
TTin 10:34
DTimin 2016-01-19
TTimax 00:44
DTimax 2016-08-28
To -1.4
Tomin -3.8
Tomax 38.4
TTomin 06:46
DTomin 2016-02-18
TTomax 16:13
DTomax 2016-07-19
Wissam Roujoulah
quelle