시간과 날짜를 기준으로 대용량 파일에서 반복적으로 데이터 가져오기

시간과 날짜를 기준으로 대용량 파일에서 반복적으로 데이터 가져오기

날짜(열 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/언어/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(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

관련 정보