時間と日付に基づいて大容量ファイルから繰り返しデータをインポートする

時間と日付に基づいて大容量ファイルから繰り返しデータをインポートする

日付(列1)と時間(列2)に基づいてデータを取得します。 2列の各日付には時間があります。列1の各日付に対して、6:00~21:50:08(日)と22:00:00~5:50:00(夕方)の時間に基づいて、すべてのフィールドを含む2つのファイルが作成されます。指定された時刻(date_dayとdate_night)に基づいて各日付に対して2つのファイルを取得します。

入力ファイル:

Date       Time     R1      R2      R3
03/10/2023 19:00:08 19.06   39.870  5.12
03/10/2023 19:10:08 18.87   39.970  4.98
03/10/2023 19:20:08 18.68   39.940  4.80
03/10/2023 19:30:08 18.84   40.110  5.01
03/10/2023 19:40:08 18.89   38.960  4.64
03/10/2023 19:50:08 18.60   39.100  4.43
03/10/2023 23:30:08 18.03   34.200  2.03
03/10/2023 23:40:08 17.94   33.930  1.84
03/10/2023 23:50:08 17.87   33.840  1.74
03/11/2023 00:00:08 17.75   33.790  1.61
03/11/2023 00:10:08 17.96   34.060  1.91
03/11/2023 00:20:08 18.13   33.690  1.91
03/11/2023 00:30:08 17.91   33.620  1.68

結果ファイル:

03/10/2023_day

Date        Time    R1      R2      R3
03/10/2023 19:00:08 19.06   39.870  5.12
03/10/2023 19:10:08 18.87   39.970  4.98
03/10/2023 19:20:08 18.68   39.940  4.80
03/10/2023 19:30:08 18.84   40.110  5.01
03/10/2023 19:40:08 18.89   38.960  4.64

03/10/2023_night

Date        Time     R1      R2      R3
03/10/2023 19:50:08 18.60   39.100  4.43
03/10/2023 23:30:08 18.03   34.200  2.03
03/10/2023 23:40:08 17.94   33.930  1.84
03/10/2023 23:50:08 17.87   33.840  1.74

03/11/2023_night:

Date       Time      R1     R2      R3
03/11/2023 00:00:08 17.75   33.790  1.61
03/11/2023 00:10:08 17.96   34.060  1.91
03/11/2023 00:20:08 18.13   33.690  1.91
03/11/2023 00:30:08 17.91   33.620  1.68

昼と夜のファイルを取得するために、次のことを試しました。デートするたびにこの仕事を続けなければなりません。 :なしの数値を取得するために、コードの時間列から「:」を削除しました。誰でもこれをループに入れ、各日付に対して別々の昼と夜のファイルを持つことができますか?

awk '$1 ~ /03\/10\/2023/ && $2 >= 060000 && $2 <= 215000' data |sed 's/\t/,/g' > 03_10_23_day.csv
awk '$1 ~ /03\/10\/2023/ && $2 > 215000' data |sed 's/\t/,/g' > 03_10_23_night.csv

答え1

使用幸せ(以前のPerl_6)

#OUTPUT A SPECIFIED 'TIME-OF-DAY' RANGE FOR ALL DATES IN FILE:

~$ raku -e 'my $hdr = get; my @a = lines.map: *.split(" ");  \
            my @b = do for @a { .[0..1].join("T").subst(/ (\d**2) \/ (\d**2) \/ (\d**4) /, {"$2-$0-$1"} ).DateTime, .[2..*] };  \
            put $hdr; for @b {   \
                my $start = .[0].truncated-to("day") + Duration.new(21600);  \
                my $stop  = .[0].truncated-to("day") + Duration.new(71408);  \
                put $_ if  $_.[0] ~~ $start ..^ $stop };'  file 

上記(最初の答え)はRaku(Perlプログラミング言語の1つ)を使った方法です。 Rakuを使えば良い点の一つはISO-8601 日時内蔵されています。上記は入力ラインをフィルタリングして定義された範囲$start .. $stop内で出力を提供します。範囲..^演算子(キャレットを含む)は、出力からRHS時点を除外します。

#OUTPUT A 'TIME-OF-DAY' RANGE FOR A SPECIFIED DATE IN FILE:

~$ raku -e 'my $target_date = DateTime.new("2023-03-10");   \
            say $target_date; my $hdr = get;  \
            my @a = lines.map: *.split(" "); my @b = do for @a { .[0..1].join("T").subst(/ (\d**2) \/ (\d**2) \/ (\d**4) /, {"$2-$0-$1"} ).DateTime, .[2..*] };  \
            put $hdr;  for @b {   \
                my $start = $target_date + Duration.new(21600);  \
                my $stop  = $target_date + Duration.new(71408);  \ 
                put $_ if  $_.[0] ~~ $start ..^ $stop };'    file

具体的には、上記(2番目の回答)では、$target_date「時間」範囲を定義し、その日付のみを出力に保持できます。

入力例(OPの例と最後に追加された2行):

Date       Time     R1      R2      R3
03/10/2023 19:00:08 19.06   39.870  5.12
03/10/2023 19:10:08 18.87   39.970  4.98
03/10/2023 19:20:08 18.68   39.940  4.80
03/10/2023 19:30:08 18.84   40.110  5.01
03/10/2023 19:40:08 18.89   38.960  4.64
03/10/2023 19:50:08 18.60   39.100  4.43
03/10/2023 23:30:08 18.03   34.200  2.03
03/10/2023 23:40:08 17.94   33.930  1.84
03/10/2023 23:50:08 17.87   33.840  1.74
03/11/2023 00:00:08 17.75   33.790  1.61
03/11/2023 00:10:08 17.96   34.060  1.91
03/11/2023 00:20:08 18.13   33.690  1.91
03/11/2023 00:30:08 17.91   33.620  1.68
03/12/2023 19:00:08 19.06   39.870  5.12
03/12/2023 19:10:08 18.87   39.970  4.98

出力例(1):

Date       Time     R1      R2      R3
2023-03-10T19:00:08Z 19.06   39.870  5.12
2023-03-10T19:10:08Z 18.87   39.970  4.98
2023-03-10T19:20:08Z 18.68   39.940  4.80
2023-03-10T19:30:08Z 18.84   40.110  5.01
2023-03-10T19:40:08Z 18.89   38.960  4.64
2023-03-12T19:00:08Z 19.06   39.870  5.12
2023-03-12T19:10:08Z 18.87   39.970  4.98

出力例(2):

2023-03-10T00:00:00Z
Date       Time     R1      R2      R3
2023-03-10T19:00:08Z 19.06   39.870  5.12
2023-03-10T19:10:08Z 18.87   39.970  4.98
2023-03-10T19:20:08Z 18.68   39.940  4.80
2023-03-10T19:30:08Z 18.84   40.110  5.01
2023-03-10T19:40:08Z 18.89   38.960  4.64

https://docs.raku.org/言語/temporal
https://docs.raku.org/type/DateTime
https://raku.org

答え2

数値比較の代わりに文字列比較を実行し、1回の呼び出しですべてのawk出力ファイルを生成しようとしています。awkここではループを使用することは意味がありません。

awk -v OFS=, '
  {$1 = $1} # force reformatting with comma delimiters
  NR == 1 {header = $0; next}
  {
    split($1, f, "/")
    outfile = f[1] "_" f[2] "_" substr(f[3], 3) "_" \
              ($2 >= "06:00:00" && $2 < "22:00:00" ? "day" : "night") \
              ".csv"
    if (!seen[outfile]++) print header > outfile
    print > outfile
  }' < data

$2 >= "06" && $2 < "22"ここでも働くことができます)

2023-10-03-night.csv代わりにファイル名を指定することをお勧めします03_10_23_night.csv(3月10日ではなく10月3日と仮定)。これは、たとえば国際標準の一般形式lsである時系列で表示されることを意味します。2023-10-03

答え3

仮定/理解:

  • 出力ファイル名は日付を使用して日付/に変換されます_(例03/10/2023:)03_10_2023
  • 出力ファイル名の形式はDD_MM_YYYY_dayまたは-期待される出力に基づいています(つまり、この回答ではOPのサンプルコードに示されている拡張子をDD_MM_YYY_night無視します)。.csv
  • 入力/出力フィールド区切り記号は空白です。入力/出力の例に従って(つまり、この回答ではOPの暗黙的なタブ/カンマ区切り文字を無視しますsed s/\t/,/g
  • 日付(列1)と時刻(列2)に基づいてソートされた入力データ
  • 時間範囲は次のように定義されます(OP定義に従って発生する間隔を削除)。
  • day=06:00:0021:59:59(OPで:???06:00:0021:50:08
  • night=22:00:0005:59:59(OPで:???22:00:0005:50:00
  • エントリは、ファイルではなく03/10/2023 19:50:08結果ファイルに存在する必要があります(予想出力に表示されるOPなど)。_day_night
  • OPは0[0-5](早朝)アイテムを日付_nightファイルに入れたいと思う.ㅏ)以前の日付のファイル_nightまたは雨)新しい_morningファイルとして)
  • メモ:これらの仮定/理解のいずれかが間違っている場合、OPは質問を更新してより詳細かつ明確に説明する必要があります。

サンプル入力ファイルに数行を追加します。

$ cat data
Date       Time     R1      R2      R3
03/10/2023 03:10:08 19.06   39.870  5.12          # new: to be placed in '_night' file
03/10/2023 05:30:08 18.87   39.970  4.98          # new: to be placed in '_night' file
03/10/2023 19:00:08 19.06   39.870  5.12
03/10/2023 19:10:08 18.87   39.970  4.98
03/10/2023 19:20:08 18.68   39.940  4.80
03/10/2023 19:30:08 18.84   40.110  5.01
03/10/2023 19:40:08 18.89   38.960  4.64
03/10/2023 19:50:08 18.60   39.100  4.43
03/10/2023 23:30:08 18.03   34.200  2.03
03/10/2023 23:40:08 17.94   33.930  1.84
03/10/2023 23:50:08 17.87   33.840  1.74
03/11/2023 00:00:08 17.75   33.790  1.61
03/11/2023 00:10:08 17.96   34.060  1.91
03/11/2023 00:20:08 18.13   33.690  1.91
03/11/2023 00:30:08 17.91   33.620  1.68

メモ:ファイルにコメントが含まれていません。

アイデアawk

awk '
NR==1               { hdr = $0; next }                        # save header

$1 != prev_dt       { close(out_day)                          # if new date then close output files
                      close(out_night)

                      prev_dt = out_dt = $1                   # make note of new date
                      gsub(/\//,"_",out_dt)                   # replace "/" with "_"

                      out_day   = out_dt "_day"               # define new output file names
                      out_night = out_dt "_night"

                      hdr_flag_day = hdr_flag_night = 1       # reset "print header?" flag
                    }

$2 >= "06:00:00" &&                                           # "day"
$2 <= "21:59:59"    { if ( hdr_flag_day ) {
                         print hdr > out_day
                         hdr_flag_day = 0
                      }
                      print $0 > out_day
                      next
                    }

                    { if ( hdr_flag_night ) {                 # "night"
                         print hdr > out_night
                         hdr_flag_night = 0
                      }
                      print $0 > out_night
                    }
' data

これで以下が生成されます。

$ head 03*20??_[dn]*
==> 03_10_2023_day <==
Date       Time     R1      R2      R3
03/10/2023 19:00:08 19.06   39.870  5.12
03/10/2023 19:10:08 18.87   39.970  4.98
03/10/2023 19:20:08 18.68   39.940  4.80
03/10/2023 19:30:08 18.84   40.110  5.01
03/10/2023 19:40:08 18.89   38.960  4.64
03/10/2023 19:50:08 18.60   39.100  4.43

==> 03_10_2023_night <==
Date       Time     R1      R2      R3
03/10/2023 03:10:08 19.06   39.870  5.12
03/10/2023 05:30:08 18.87   39.970  4.98
03/10/2023 23:30:08 18.03   34.200  2.03
03/10/2023 23:40:08 17.94   33.930  1.84
03/10/2023 23:50:08 17.87   33.840  1.74

==> 03_11_2023_night <==
Date       Time     R1      R2      R3
03/11/2023 00:00:08 17.75   33.790  1.61
03/11/2023 00:10:08 17.96   34.060  1.91
03/11/2023 00:20:08 18.13   33.690  1.91
03/11/2023 00:30:08 17.91   33.620  1.68

関連情報