ddMMyyyy-HHmm+0300
나는 내 타임스탬프 형식( )을 WEKA 데이터 분석 시스템에서 사용하는 타임스탬프/시간/... 형식( ) 으로 변환하는 Perl/... 메서드를 고안하려고 합니다 . 원래는 명령을 통해 yyyy-MM-dd'T'HH:mm:00
WEKA 데이터 파일을 만들고 . 제 생각엔 (3)번 방법이 가장 타당하다고 생각합니다. 즉, (Deathgrip) 함수를 직접 사용하는 것입니다.paste
AWK
POSIX::strftime
- 섹션 1의 어려움
- 섹션 2의 데이터에 따옴표를 사용하지 않는 더 쉬운 방법
POSIX::strftime
방법 및 유사한 스레드Perl strptime 형식은 strftime과 다릅니다.
입력 예
23072017-2200+0300
예상 출력
2017-07-23'T'22:00:00
따옴표는 없지만 밑줄이 포함된 CSV 줄의 전체 예이므로 더 어려울 수 있습니다.
Ni, Aika, Aika_l, Un, Unen, Unen_kesto, Uniluokat_R, Uniluokat_k, Uniluokat_s, HRV_RMSSD_a, HRV_RMSSD_i, Kokonaisp, Palautumisen_k, Hermoston_t, Syke_ave_m, Syke_a, Syke_l, Hengitystiheys_ave_m, Hengitystiheys_a, Hengitystiheys_min_a, Liikeaktiivisuus_l, Liikeaktiivisuus_a, Paivamaara_l
"Masi", 23072010-2200+0300, 24072010-0600+0300, 70, 7h40, 6h30, 1h40, 3h40, 1h10, 67.0, 43.0, 24.0, 430, 30, 70, 50, 40, 20, 10, 10, 150, 260, 24.10.2010
"Masi", 23072010-2200+0300, 24072010-0600+0300, 70, 7h40, 6h30, 1h40, 3h40, 1h10, 67.0, 43.0, 24.0, 430, 30, 70, 50, 40, 20, 10, 10, 150, 260, 24.10.2010
예상 출력
Ni, Aika, Aika_l, Un, Unen, Unen_kesto, Uniluokat_R, Uniluokat_k, Uniluokat_s, HRV_RMSSD_a, HRV_RMSSD_i, Kokonaisp, Palautumisen_k, Hermoston_t, Syke_ave_m, Syke_a, Syke_l, Hengitystiheys_ave_m, Hengitystiheys_a, Hengitystiheys_min_a, Liikeaktiivisuus_l, Liikeaktiivisuus_a, Paivamaara_l
"Masi", 2010-07-23'T'22:00:00, 2010-07-24'T'06:00:00, 70, 7h40, 6h30, 1h40, 3h40, 1h10, 67.0, 43.0, 24.0, 430, 30, 70, 50, 40, 20, 10, 10, 150, 260, 24.10.2010
"Masi", 2010-07-23'T'22:00:00, 2010-07-24'T'06:00:00, 70, 7h40, 6h30, 1h40, 3h40, 1h10, 67.0, 43.0, 24.0, 430, 30, 70, 50, 40, 20, 10, 10, 150, 260, 24.10.2010
1. 호출할 수 있는 스크립트를 사용해 보세요.script.pl filename
Text::CSV
내 데이터 세트가 사용 사례보다 단순하기 때문에 파서가 사용하기에는 너무 복잡하다고 생각합니다 . 그래서 간단한 정규식 접근 방식이 가능하다고 생각합니다.
#!/usr/bin/env perl
# https://stackoverflow.com/a/33995620/54964
## Data prepared like this for the script
# paste -d" " log.csv data.csv | awk '{$1=""; print $0}' > weka.data.csv
# cp $HOME/Data/weka.data.csv $HOME/Workspace/
#
# Maybe, this all could be integrated into Perl script
use strict;
use warnings;
use Text::CSV;
my $csv = Text::CSV->new( { binary => 1, eol => "\n" } );
while ( my $row = $csv->getline( \*ARGV ) ) {
s/\n/ /g for @$row;
$csv->print( \*STDOUT, $row );
# TODO regex
#convert ddMMyyyy-HHmm+0300 to yyyy-MM-dd'T'HH:mm:00
}
2. Perl 정규 표현식 방법
변수 대체가 없기 때문에(예: dd
결과 전달) 메서드에 대한 의사 코드가 작동하지 않습니다.
# TODO s/ddMMyyyy-HHmm+0300/$3-$2-$1'T'$4:$5:00/;
perl -pe s/([0-3][0-9])(([0-1][0-9]))(20[0-9]{2})([0-2][0-9])([0-5][0-9])+0300/$3-$2-$1'T'$4:$5:00/;
어디
dd
통과([0-3][0-9])
/$3
- 마찬가지로 /
MM
의 경우([0-1][0-9])
$2
yyyy
비슷하다(20[0-9]{2})
/$1
-
문자 그대로HH
24시간([0-5][0-9])
/$4
mm
통과([0-5][0-9])
) /$5
+0300
/ 간단히 삭제
정규식에 더 읽기 쉬운 형식이 있으면 좋을 것입니다.
댓글로 Sundeep의 제안을 테스트해 보세요.
암호
#!/bin/bash
# https://stackoverflow.com/a/33995620/54964
s='"Masi", 23072010-2200+0300, 24072010-0600+0300 70, 7h40'
echo "$s" | perl -pe 's/\b(\d\d)(\d\d)(\d{4})-(\d\d)(\d\d)\+\d{4}\b/$3-$2-$1\x27T<200c><200b>\x27$4:$5:00/g' y $csv = Text::CSV->new( { binary => 1, eol => "\n" } );
한 줄의 출력이 예상대로입니다.
"Masi", 2010-07-23'T'22:00:00, 2010-07-24'T'06:00:00, 70, 7h40
변수 내용을 바꾸는 것만으로도 전체 라인에 적용되어 s
예상대로 출력됩니다.
"Masi", 2010-07-23'T'22:00:00, 2010-07-24'T'06:00:00, 70, 7h40, 6h30, 1h40, 3h40, 1h10, 67.0, 43.0, 24.0, 430, 30, 70, 50, 40, 20, 10, 10, 150, 260, 24.10.2010
여러 줄 방법과 헤더 건너뛰기 기능을 갖춘 TODO 완전한 방법
Deathgrip 테스트에 대한 적극적인 제안
암호
#!/usr/bin/env perl
# https://stackoverflow.com/a/33995620/54964
use strict;
use warnings;
# https://stackoverflow.com/a/20007784/54964
# http://perldoc.perl.org/POSIX.html
use Time::Piece;
use POSIX;
# TODO breaks because of false brackets
#my $input = '"Masi", 2010-07-23'T<200c><200b>'22:00:00, 2010-07-24'T<200c><200b>'06:00:00, 70, 7h40, 6h30, 1h40, 3h40, 1h10, 67.0, 43.0, 24.0, 430, 30, 70, 50, 40, 20, 10, 10, 150, 260, 24.10.2010'
my $str = '23072017-2200+0300';
my $f = '%d%m%dY-%H%M+0300';
#my $t = POSIX::strftime($str, $f); # fails!
my $t = strftime($str, $f); # fails!
print "$t\n";
산출
Usage: POSIX::strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1) at prepare.data3.pl line 22.
운영 체제: 데비안 9
답변1
$ perl -pe 's/\b(\d\d)(\d\d)(\d{4})-(\d\d)(\d\d)\+\d{4}\b/$3-$2-$1\x27T\x27$4:$5:00/g' ip.csv
Ni, Aika, Aika_l Un, Unen, Unen_kesto, Uniluokat_R, Uniluokat_k, Uniluokat_s, HRV_RMSSD_a, HRV_RMSSD_i, Kokonaisp, Palautumisen_k, Hermoston_t, Syke_ave_m, Syke_a, Syke_l, Hengitystiheys_ave_m, Hengitystiheys_a, Hengitystiheys_min_a, Liikeaktiivisuus_l, Liikeaktiivisuus_a, Paivamaara_l
"Masi", 2010-07-23'T'22:00:00, 2010-07-24'T'06:00:00 70, 7h40, 6h30, 1h40, 3h40, 1h10, 67.0, 43.0, 24.0, 430, 30, 70, 50, 40, 20, 10, 10, 150, 260, 24.10.2010
"Masi", 2010-07-23'T'22:00:00, 2010-07-24'T'06:00:00 70, 7h40, 6h30, 1h40, 3h40, 1h10, 67.0, 43.0, 24.0, 430, 30, 70, 50, 40, 20, 10, 10, 150, 260, 24.10.2010
\b
단어 경계입니다(\d\d)
두 개의 연속 숫자를 캡처하고(\d{4})
그 중 4개를 캡처하는 등의 작업을 수행합니다.\x27
작은따옴표에 사용됩니다. 그 뒤에 관련 없는 숫자가 있을 수 있는 경우 8진수 표현을 사용하는 것이 더 나을 수도 있습니다.\047
- 검색 및 바꾸기는 특정
ddMMyyyy-HHmm+0300
형식만 대상으로 하기 때문에 헤더에는 영향을 주지 않습니다. 하지만 필요한 경우if $.>1
대체 명령 뒤에 추가하면 됩니다.
paste+awk
입력을 생성하는 데 사용된 명령을 이 명령에 쉽게 통합할 수 있지만 해당 정보를 질문에 추가해야 합니다 .
답변2
내가 할 일은 다음과 같습니다.
#!/usr/bin/env perl
# https://stackoverflow.com/a/33995620/54964
use strict;
use warnings;
# https://stackoverflow.com/a/20007784/54964
# http://perldoc.perl.org/POSIX.html
use POSIX qw(strftime);
use DateTime;
use DateTime::Format::Strptime qw(strptime);
my $str = '23072017-2200+0300';
my $dtime = strptime( '%d%m%Y-%H%M%z', $str );
my $f = '%Y-%m-%d\'T\'%H:%M:%S';
my $t = strftime( $f, 0, $dtime->minute, $dtime->hour, $dtime->day, $dtime->month-1, $dtime->year-1900, -1, -1, $dtime->time_zone );
print "$t\n";
시간 필드에서 예상대로 출력
2017-07-23'T'22:00:00