sed/awk/grep コマンドを使用して txt ファイルの値を編集する

sed/awk/grep コマンドを使用して txt ファイルの値を編集する

私はLa Crosse WS2350気象観測所を5年間使用してきました。気象観測所から提供されるデータは、RPIのopen2300を使用して処理されます。これは非常にうまく機能します。しかし、温度データ(センサー)が間違っています。温度データは1℃低いです。

センサーを校正できないため、気象観測所から抽出したファイルの温度値を変更したいと思います。

テキストファイル(current.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 -2.4
Tomin -4.8
Tomax 37.4
TTomin 06:46
DTomin 2016-02-18
TTomax 16:13
DTomax 2016-07-19
...

「To」、「Tomin」、「Tomax」の値に+1を追加し、テキストファイルを正しい値で上書きしたいと思います。

sedとawkコマンドを見た後、私は私が最新バージョンではないことに気づきました。誰でも私を案内できますか?ありがとう

編集する:

別のファイルws2308.logを忘れました。 15分ごとに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 

変更する必要がある値は、5番目のフィールド(最初の-1.2)です。

また、最後の行の温度値に1を加算し、最後の行を正しい値で上書きする必要があります。プログラムPHPは最後の行のみを考慮し、結果をチャートに表示できます。

ありがとう

答え1

これは処理するためのややより慣用的なAWKバリアントですcurrent.txtスティーブの2番目の答えもっと寛容的です! ):

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

Toこれはで始まり、後ろに何かがあるmin行を探しmax、その後に空白が続く行を探します。一致する行に対して、最初のフィールドと2番目のフィールドがインクリメントされると、デフォルトの出力フィールド区切り文字(スペース)で区切られて印刷されます。その後、次の行にジャンプします。他の行はすべてそのまま印刷されます(1AWKのショートカットです)。

新しい値でファイルを上書きするのはおそらく良い考えではありません。値が変更されたかどうかはわかりません...毎回デバイスからファイルを検索する場合は適用されません。

同じ推論が適用されるので、ws2308.log毎回完全に処理します。

$ 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

最後の行だけが必要な場合:

$ 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

または、最後の行のみを含むファイルが必要な場合変更:

$ 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

答え2

これが解決策です。 「To」、「Tomin」、または「Tomax」で始まり、空白が続く行の場合は、最初のフィールドを印刷してから2番目のフィールドを1ずつ増やします。それ以外の場合は、行全体が印刷されます。

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

答え3

もう一つの方法は少し ゴルフをする

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

答え4

その後、次のようになります。

  1. まず、すべての行を繰り返します。
  2. 次に、最初の項目を確認し、要件を満たしていることを確認します。
  3. その後、一致する場合は印刷し、行の次の項目に+1を追加します。
  4. それ以外の場合は、印刷して次の項目を印刷してください。

    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
    

出力

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

関連情報