根据日期(第 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_day
orDD_MM_YYY_night
- 根据预期输出(即,对于这个答案,我们将忽略.csv
OP 示例代码中所示的扩展名) - 输入/输出字段分隔符是空格 - 根据示例输入/输出(即,对于这个答案,我们将忽略 OP 中隐含的制表符/逗号分隔符
sed s/\t/,/g
) - 输入数据已按日期(第 1 列)和时间(第 2 列)排序
- 时间范围定义如下(消除OP定义引入的间隙):
day
=06:00:00
到21:59:59
(与 OP:06:00:00
到21:50:08
???)night
=22:00:00
到05:59:59
(与 OP:22:00:00
到05: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