日付(列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: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
結果ファイルに存在する必要があります(予想出力に表示される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