다음 형식의 레코드가 포함된 파일이 있습니다.
D20220327,S2927,977,1
D20220328,S2927,977,1
D20220329,S2927,977,1
D20220330,S2927,977,1
D20220331,S2927,977,1
D20220401,S2927,977,1
D20220402,S2927,977,1
D20220403,S2927,977,1
D20220404,S2927,977,1
그러나 이 시간을 과거 7일 전으로 이동하는 변환을 적용한 후 3월 28일부터 4월 3일까지의 날짜에는 작동하지 않지만, 동일한 코드 논리는 3월 27일과 4월 4일에는 잘 작동합니다. 왜 일주일 동안만 작동하지 않는지 이해가 되지 않습니다. 이것이 출력이다
D20220320,S2927,977,1 -- correct
D20220320,S2927,977,1 -- incorrect
D20220321,S2927,977,1 -- incorrect
D20220322,S2927,977,1 -- incorrect
D20220323,S2927,977,1 -- incorrect
D20220324,S2927,977,1 -- incorrect
D20220325,S2927,977,1 -- incorrect
D20220326,S2927,977,1 -- incorrect
D20220328,S2927,977,1 -- correct
여기에 사용된 논리는 다음과 같습니다.
BEGIN {
OFS = FS = ","
}
{
t = mktime(sprintf("%4d %.2d %.2d 00 00 00",
substr($1,2,4),
substr($1,6,2),
substr($1,8,2)));
$1 = substr($1,1,1) strftime("%Y%m%d", t - 7*24*60*60)
print
}
답변1
귀하의 계산은 현지 시간으로 이루어지며 3월 27일 일광 절약 시간제 전환의 영향을 받게 됩니다.
계산에 UTC 시간을 사용하려면(Unix 타임스탬프는 현지 시간이 아님) 최신 버전의 GNU를 사용하고 awk
추가 인수를 1
마지막 인수로 전달해야 합니다 mktime()
.
t = mktime(sprintf("%4d %.2d %.2d 00 00 00",
substr($1,2,4),
substr($1,6,2),
substr($1,8,2)), 1);
이는 GNU 버전 4.2.0+ awk
에서 사용 가능한 GNU 확장 입니다.awk
대안으로 자정(UTC) 주변 시간을 참조 시간으로 사용하지 않을 수 있습니다.
t = mktime(sprintf("%4d %.2d %.2d 12 00 00",
substr($1,2,4),
substr($1,6,2),
substr($1,8,2)));
이를 통해 이전 GNU 구현 및 필요한 기능을 갖춘 awk
기타 구현 에서 작동할 수 있습니다 .awk
또 다른 옵션은 변경된 현지 시간대로 스크립트를 실행하는 것입니다.
TZ=UTC awk -f script.awk inputfile
이는 실행 스크립트에 TZ
환경 변수를 설정하여 관련 기능에서 사용하는 시간대를 변경합니다.UTC
awk
mktime()
답변2
Raku(이전 Perl_6) 사용
raku -pe 's/^ D <( (\d**4)(\d**2)(\d**2) )> \, /{ "$0-$1-$2".Date.earlier(:7days).Str.subst("-", :g); }/;'
입력 예(빈 줄 제거):
D20220327,S2927,977,1
D20220328,S2927,977,1
D20220329,S2927,977,1
D20220330,S2927,977,1
D20220331,S2927,977,1
D20220401,S2927,977,1
D20220402,S2927,977,1
D20220403,S2927,977,1
D20220404,S2927,977,1
예제 출력:
D20220320,S2927,977,1
D20220321,S2927,977,1
D20220322,S2927,977,1
D20220323,S2927,977,1
D20220324,S2927,977,1
D20220325,S2927,977,1
D20220326,S2927,977,1
D20220327,S2927,977,1
D20220328,S2927,977,1
간단히 말해서 Raku의 한 줄씩(자동 인쇄) -pe
플래그는 친숙한 연산자와 함께 사용됩니다 s///
. 숫자는 괄호와 함께 일치 변수 $0
, $1
및 에 캡처되고 $2
캡처 마커는 <( … )>
일치의 다른 모든 요소를 제거하는 데 사용됩니다.
대신 Raku는 { … }
블록 내에서 코드를 실행합니다. , 및 캡처는 적절한 대시( )로 문자열화되며 문자열은 메소드를 호출할 수 있는 객체로 인식됩니다 $0
. [참고: 일부 사용자는 더 친숙한 구문을 작성하는 것을 발견할 수 있습니다. 두 형식 모두 유효합니다.] 객체가 7일로 다시 설정되면 기호로 표시되어 반환 시 대시( )를 제거하는 데 사용됩니다.$1
$2
-
Date
earlier(:7days)
earlier(days => 7)
Date
Str
subst
-
https://docs.raku.org/routine/Date
https://docs.raku.org/routine/Dateish
https://raku.org