Modifier les valeurs dans un fichier txt avec la commande sed / awk / grep

9

Depuis 5 ans, j'utilise une station météo La Crosse WS2350. Les données fournies par la station météo sont traitées avec open2300 sur RPI. Cela fonctionne très bien. Cependant, les données de température sont fausses (capteur). Les données de température sont inférieures de 1 ° C.

Comme je ne peux pas calibrer le capteur, je souhaite modifier la valeur de température du fichier extrait de la station météo.

Ce fichier texte (current.txt) contient:

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

Je veux ajouter +1 aux valeurs "À", "Tomin", "Tomax" et écraser le fichier texte avec les valeurs correctes.

Après avoir regardé les commandes sed et awk, je me rends compte que je suis dépassé. Quelqu'un peut-il me guider? Merci

Éditer :

J'ai oublié un autre fichier: ws2308.log Toutes les 15 minutes, une nouvelle ligne est ajoutée au fichier 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 -1.2 -3.3 64 87 0.0 135.0 SE -1.2 569.80 1015.700 

La valeur à modifier est le 5ème champ (le premier -1,2)

Il est également nécessaire que sur la dernière ligne, la valeur de la température soit incrémentée de 1 et écrase la dernière ligne avec la valeur correcte. Seule la dernière ligne sera prise en compte par le programme php qui permet d'afficher les résultats dans un graphique.

Merci

Ookpik
la source

Réponses:

12

Voici une variante AWK légèrement plus idiomatique à traiter current.txt( la deuxième réponse de steve est encore plus idiomatique!):

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

Cela recherche les lignes commençant par To, suivies de rien min, ou max, suivies d'un espace; pour les lignes correspondantes, il imprime le premier champ et le deuxième champ, incrémenté, séparés par le séparateur de champ de sortie par défaut (espace). Il passe ensuite à la ligne suivante. Toutes les autres lignes sont imprimées telles quelles ( 1est un raccourci pour cela dans AWK).

Notez que remplacer le fichier par les nouvelles valeurs n'est probablement pas une bonne idée: vous ne saurez pas si les valeurs ont été corrigées ou non ... Si vous récupérez le fichier à partir de l'appareil à chaque fois, cela ne s'applique pas.

Le même raisonnement s'applique à ws2308.log, nous allons donc simplement le traiter dans son intégralité à chaque fois:

$ 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

Si vous ne voulez que la dernière ligne:

$ 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

ou si vous souhaitez que le fichier avec uniquement la dernière ligne soit modifié :

$ 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
la source
10

Voici une solution. Pour toutes les lignes commençant par «À», «Tomin» ou «Tomax» suivies d'un espace, imprimez le premier champ puis le deuxième champ incrémenté de 1. Sinon, imprimez simplement la ligne complète.

$ 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
la source
5

Une autre approche, légèrement golfée .

$ 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
la source
3
Bien (donc +1), mais vous auriez pu juste ajouter cela comme une modification à votre réponse existante!
Stephen Kitt du
@Scott -isur awkajoute un fichier inclus, il n'y a rien comme sedde » -il'option.
Stephen Kitt
@StephenKitt: D'oh! Je le savais.
Scott
5

Une approche Perl:

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

Le -ifait écraser le fichier d'origine, il n'imprimera donc rien, il changera directement le fichier.

Les -amarques perlagissent comme awk, divisant son entrée sur l'espace blanc (ou tout autre élément donné par -F) dans le tableau @F. Ainsi, le deuxième champ sera $F[1]parce que les tableaux commencent à compter à 0. Le script remplacera donc le deuxième champ par lui-même incrémenté de un sur les lignes commençant par To.

terdon
la source
2

Cela fera le travail:

  1. Le premier passera par toutes les lignes
  2. Vérifiez ensuite le premier élément et vérifiez s'il correspond à ce que vous voulez.
  3. Ensuite, s'il correspond, imprimez-le et ajoutez +1 à l'élément suivant de la ligne
  4. Sinon il suffit de l'imprimer et d'imprimer l'élément suivant

    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
    

PRODUCTION

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
la source