Edite valores en un archivo txt con el comando sed / awk / grep


9

Durante 5 años, uso una estación meteorológica La Crosse WS2350. Los datos proporcionados por la estación meteorológica se procesan con open2300 en RPI. Esto funciona muy bien Sin embargo, los datos de temperatura son falsos (sensor). Los datos de temperatura son 1 ° C más bajos.

Como no puedo calibrar el sensor, quiero cambiar el valor de temperatura del archivo extraído de la estación meteorológica.

Este archivo de texto (current.txt) contiene:

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

Quiero agregar +1 a los valores "Para", "Tomin", "Tomax" y sobrescribir el archivo de texto con los valores correctos.

Después de mirar los comandos sed y awk, me doy cuenta de que estoy desactualizado. ¿Alguien puede guiarme? Gracias

Editar:

Olvidé otro archivo: ws2308.log Cada 15 minutos se agrega una nueva línea al archivo 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 

El valor a modificar es el quinto campo (el primer -1.2)

También es necesario que en la última línea, el valor de la temperatura se incremente en 1 y sobrescriba la última línea con el valor correcto. Solo la última línea será tomada en cuenta por el programa php que permite visualizar los resultados en un gráfico.

Gracias

Respuestas:


12

Aquí hay una variante AWK un poco más idiomática para procesar current.txtla segunda respuesta de Steve es aún más idiomática!):

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

Esto busca líneas que comienzan con To, seguidas de nada min, o max, seguidas de un espacio; para líneas coincidentes, imprime el primer campo y el segundo campo, incrementado, separado por el separador de campo de salida predeterminado (espacio). Luego salta a la siguiente línea. Todas las demás líneas se imprimen tal cual ( 1es un acceso directo para esto en AWK).

Tenga en cuenta que sobrescribir el archivo con los nuevos valores probablemente no sea una buena idea: no sabrá si los valores se han corregido o no ... Si recupera el archivo del dispositivo cada vez, eso no se aplica.

Se aplica el mismo razonamiento ws2308.log, así que procesémoslo en su totalidad cada vez:

$ 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 solo quieres la última línea:

$ 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

o si desea cambiar el archivo con solo la última línea :

$ 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

10

Aquí hay una solución. Para cualquier línea que comience con "Para", "Tomin" o "Tomax" seguido de un espacio, imprima el primer campo y luego el segundo campo incrementado en 1. De lo contrario, simplemente imprima la línea completa.

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

5

Otro enfoque, ligeramente golfizado .

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

3
Agradable (entonces +1), ¡pero podría haberlo agregado como una edición a su respuesta existente!
Stephen Kitt

@Scott -ion awkagrega un archivo de inclusión, no se parece en nada a sedla -iopción.
Stephen Kitt

@StephenKitt: D'oh! Lo sabía.
Scott

5

Un enfoque de Perl:

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

Esto -ihace que sobrescriba el archivo original, por lo que no imprimirá nada, cambiará el archivo directamente.

El -ahace perlactuar como awk, dividiendo su entrada en whitesapce (o cualquier otra cosa dada por -F) en la matriz @F. Por lo tanto, el segundo campo se debe a $F[1]que las matrices comienzan a contar en 0. Por lo tanto, el script reemplazará el segundo campo por sí mismo incrementado en uno en las líneas que comienzan con To.


2

Esto hará el trabajo:

  1. Primero pasará por todas las líneas
  2. Luego verifique el primer elemento y verifique si coincide con lo que desea.
  3. Luego, si coincide, imprímalo y agregue +1 al siguiente elemento en la línea
  4. De lo contrario, simplemente imprímalo e imprima el siguiente elemento

    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
    

SALIDA

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.