データのない行を前の行のデータに置き換える方法

データのない行を前の行のデータに置き換える方法

入力する

Time      Value  Flag
06:15:10  49.95  Actual
00:00:00  0.00  NoValue
06:22:50  49.94  Actual
06:23:00  49.93  Actual
06:23:10  49.93  Actual
06:23:20  49.93  Actual
06:23:30  49.93  Actual
06:24:40  49.92  Actual
00:00:00  0.00  NoValue

「NoValue」を含む行を置き換える必要があります。時間は10秒単位で最後に記録された時間に置き換えられます(10秒)。値は最後に記録されたタイムスタンプに置き換えられます。実際の値に置き換えられます。

私の結果は次のように表示されます。

Time      Value  Flag
06:15:10  49.95  Actual
06:15:20  49.95  Actual
06:22:50  49.94  Actual
06:23:00  49.93  Actual
06:23:10  49.93  Actual
06:23:20  49.93  Actual
06:23:30  49.93  Actual
06:24:40  49.92  Actual
06:24:50  49.92  Actual

答え1

awk -F'[: ]+' -v addSec=10 '
 NR>1 && /Actual/{
     sec=(($1*3600)+($2*60)+$3) +addSec;
     prevTime=sprintf("%02d:%02d:%02d", sec/3600, sec%3600/60, sec%60) OFS $4 OFS $5;
 }
 /NoValue/{ $0=prevTime }1
' infile

答え2

この試み:

catnova | tr -s "" | awk -F "[:]" -f val.awk

どこ:

cat noval 
06:15:10  49.95  Actual
00:00:00  0.00  
06:22:50  49.94  Actual
06:23:00  49.93  Actual
06:23:10  49.93  Actual
06:23:20  49.93  Actual
06:23:30  49.93  Actual
06:24:40  49.92  Actual
00:00:00  0.00  

そして

cat val.awk
{
    if($5=="") {
        print g
                   }
        else {
               print $0
           $3=$3+10
               if ($3>59){
        $3=$3-60
        $2=$2+1
               }
               if ($2>59){
                  $2=$2-60
                  $1=$1+1
               }
if(length($1)<2) {$1="0"$1}
if(length($2)<2) {$2="0"$2}
if(length($3)<2) {$3="0"$3}
               g=$1":"$2":"$3" "$4" "$5
              }
}

結果:

06:15:10 49.95 Actual
06:15:20 49.95 Actual
06:22:50 49.94 Actual
06:23:00 49.93 Actual
06:23:10 49.93 Actual
06:23:20 49.93 Actual
06:23:30 49.93 Actual
06:24:40 49.92 Actual
06:24:50 49.92 Actual

注:awkを使用して、コロン(:)文字とスペースに沿って各行を分割します。これにより、タイムスタンプの3つのコンポーネント(列1、2、3)にアクセスして潜在的に10を追加できます。複数のスペースを1つに圧縮するには、trを使用します。 awkのFフラグは、操作のためにコロンおよび/またはスペースに沿って行を破るように設定されています。

答え3

タイムスタンプが適用される日付とタイムゾーンを知らず、日付と時刻を理解するユーティリティ(例:単純な数学ではない)を使用しないと、既存の時間に10秒を加えて新しい時間を決定することはできません。 time is以下の結果は与えられた時間に10秒を加え、夏時間とうるう秒の影響を受けます。

入力タイムスタンプの開始日が今日であると仮定し、GNU awkを使用して時間関数を処理します(DSTを処理しますが、POSIXエポック時間を処理するすべてのツールと同様に、うるう秒を処理しないので、気にしないことを願っています)。それについて):

$ cat tst.awk
BEGIN {
    OFS = "  "
    prevDate = (date=="" ? strftime("%Y %m %d") : date)
}
NR == 1 {
    print
    next
}
$3 == "NoValue" {
    prevTime = gensub(/:/," ","g",prevLine[1])
    prevSecs = mktime(prevDate " " prevTime)
    currSecs = prevSecs + 10
    prevDate = strftime("%Y %m %d",currSecs)
    $1 = strftime("%T",currSecs)
    $2 = prevLine[2]
    $3 = prevLine[3]
}
{
    print
    split($0,prevLine)
}

$ awk -f tst.awk file
Time      Value  Flag
06:15:10  49.95  Actual
06:15:20  49.95  Actual
06:22:50  49.94  Actual
06:23:00  49.93  Actual
06:23:10  49.93  Actual
06:23:20  49.93  Actual
06:23:30  49.93  Actual
06:24:40  49.92  Actual
06:24:50  49.92  Actual

コンピュータに設定されているタイムゾーンとは異なるタイムゾーンで時間計算を適用するには、上記の作業を実行する前にシェル変数を適切に設定するか、TZ呼び出しにUTCフラグを設定してください。mktime()strftime()https://www.gnu.org/software/gawk/manual/gawk.html#Time-Functions

今日とは異なる開始日を使用するには、awk -v date='2021 10 03' -f tst.awk file目的のYYYY MM DD形式で日付を提供するスクリプトを呼び出します。

上記は処理方法を説明していないため、タイムスタンプは常に入力の2行目に入力されると想定しています。

@PhilipCoulingがコメント(または他のライブラリ)で指摘したように、mktime()DSTが終了したときに切り替え間隔中にDSTがある時間帯の場合、日付と時刻を提供するだけではエポック以降の秒を確実に返すことはできません(DSTが正常に起動します) 。 )))。彼らが提供する例は次のとおりです。

イギリスでは、2022年10月30日午前01:30:00の日時が2回発生します。これは、時計が午前2時に達すると、DSTが終了し、時計が午前1時に1時間後に移動するためです。したがって、1:30はDSTが終了する前に1回、DSTが終了した後に1回発生します。ファイルには、どちらを記述するかについての情報は含まれていません。ファイルは、DSTが終了したかどうかを知らせません。

答え4

使用幸せ(以前のPerl_6)

~$ raku -e 'my @init = [Z=>] lines[0].words, (DateTime.new("2024-01-01T00:00:00Z"), "0.00", "Initial"); 
            put @init.map(*.key).join("\t"); 
            for lines.map(*.words) -> ($t,$v,$f) { 
                if $f eq "NoValue" { 
                    put join "\t", @init[0].value.hh-mm-ss, @init[1..*].map(*.value) andthen 
                    @init[0] = @init[0].key => @init[0].value.later(:10seconds); 
                } else { 
                    put join "\t", ($t,$v,$f) andthen  
                    @init = [Z=>] 
                            @init.map(*.key), 
                            (DateTime.new("2024-01-01T" ~ $t ~ "Z").later(:10seconds),$v,$f) 
                        } 
                };'  file.txt

DateTimeRakuは、ISO 8601オブジェクトを組み込んだPerlファミリのプログラミング言語です。上記では、line[0]最初の行()をヘッダーとして読み取り、初期値(初期タイムスタンプを含む)でキーと値のペアを生成しますDateTime。縮小メタ演算子は、[Z=>]次の2つのリストをキーと値のペアにまとめて「圧縮」して、配列@init(つまり、ペアの配列)に割り当てます。ヘッダー行を再構成するためにすぐに出力put(タブに接続)されます。\t

ここで繰り返します。各行は、ブロック内で使用する一時変数に割り当てられている(つまり列)にマッピングされ分類さlinesれます。words$t,$v,$f

  • $fフラグ文字列が「NoValue」と等しい場合、そのeq値が出力されます。@init次にタイムスタンプを追加します。
  • $fフラグne文字列が「NoValue」と等しくない場合、行($t,$v,$f)の値が出力され、配列@init($t,$v,$f)デフォルト/以前の値を置き換える新しい値で更新されます。これによりタイムスタンプが増えます。

Rakuの1つの利点は、DateTimeこれらの機能を使用して、later(:10seconds)次の「NoValue」に表示される行を補間するためにタイムスタンプに10秒を追加できることです。また、hh-mm-ss時間部分のみを返すことができます(2024-01-01この日付は最終的に削除されるため、任意の日付を使用します)。

入力例(OPの入力例、NoValue最後に追加行を含む):

Time      Value  Flag
06:15:10  49.95  Actual
00:00:00  0.00  NoValue
06:22:50  49.94  Actual
06:23:00  49.93  Actual
06:23:10  49.93  Actual
06:23:20  49.93  Actual
06:23:30  49.93  Actual
06:24:40  49.92  Actual
00:00:00  0.00  NoValue
00:00:00  0.00  NoValue

出力例1(上記):

Time    Value   Flag
06:15:10    49.95   Actual
06:15:20    49.95   Actual
06:22:50    49.94   Actual
06:23:00    49.93   Actual
06:23:10    49.93   Actual
06:23:20    49.93   Actual
06:23:30    49.93   Actual
06:24:40    49.92   Actual
06:24:50    49.92   Actual
06:25:00    49.92   Actual

[上記の説明:サンプル入力の終わりにある複数の連続した「NoValue」行でタイムスタンプが正しく増加しました。]


「NoValue」初期データ行テスト:確実にするために、下から最初の()データ行を削除して最初のデータ行にすることがActualできます。00:00:00 0.00 NoValue

出力2例(上記の入力例では、最初/Actualデータ行を除く):

Time    Value   Flag
00:00:00    0.00    Initial
06:22:50    49.94   Actual
06:23:00    49.93   Actual
06:23:10    49.93   Actual
06:23:20    49.93   Actual
06:23:30    49.93   Actual
06:24:40    49.92   Actual
06:24:50    49.92   Actual
06:25:00    49.92   Actual

上記は正しく処理され、Initial推定された(人の)値を報告します。

https://www.iso.org/iso-8601-date-and-time-format.html
https://docs.raku.org/type/DateTime
https://raku.org

関連情報