根据时间和日期递归地从大文件中获取数据

根据时间和日期递归地从大文件中获取数据

根据日期(第 1 列)和时间(第 2 列)获取数据。第 2 列中的每个日期都有时间。根据第 1 列中的每个日期,将生成两个文件,其中包含基于时间 6:00 至 21:50:08(日)和 22:00:00 至 5 的所有字段: 50:00(晚上)。尝试根据指定的时间获取每个日期的两个文件,即 date_day 和 date_night 。

输入文件:

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 编程语言家族的成员)的方法。使用 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

上面(第二个答案)更具体地说,您可以定义一个$target_date并且仅在输出中保留该日期的“当天时间”范围。

示例输入(OP的示例加上最后添加的两行):

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/language/temporal
https://docs.raku.org/type/DateTime
https://raku.org

答案2

您希望在一次调用中进行字符串比较而不是数字比较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(假设它是十月三号而不是三月十号),这意味着ls例如将按时间顺序显示它们,这2023-10-03是国际标准明确的格式。

答案3

假设/理解:

  • 输出文件名将日期从 using 转换/为 date using _(例如,03/10/2023变为03_10_2023
  • 输出文件名的格式为DD_MM_YYYY_dayor DD_MM_YYY_night- 根据预期输出(即,对于这个答案,我们将忽略.csvOP 示例代码中所示的扩展名)
  • 输入/输出字段分隔符是空格 - 根据示例输入/输出(即,对于这个答案,我们将忽略 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条目应该驻留在结果_day文件中而不是_night文件中(如OP在预期输出中所示)
  • OP想要将0[0-5](清晨)条目放入日期_night文件中(而不是A)放入前一个日期的_night文件中或b)放入新_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

相关内容