요컨대, 내 주요 문제는 날짜에 따라 기록을 인쇄하는 것입니다.한 필드가 다른 필드와 한 달도 채 안 되는 차이가 납니다.. 모든 날짜가 포함되어 있습니다.월 일 년체재.
|
특히 다음 기준을 충족하는 경우 파이프( )로 구분된 필드 108개를 포함하는 파일에서 레코드를 추출하려고 합니다 .
날짜 필드 14와 61에는 10월 데이터가 포함되어야 합니다. #Resolved
날짜 필드 14는 날짜 필드 15 + 1개월보다 작아야 합니다($15 < $14+ 1개월) #Unresolved
내 코드:
awk -F'|' '{ if ($14 ~ /10-..-2016/ && $61 ~ /10-..-2016/ && $15< date -d '$14 1 month' ) print $0}' <input >output
작동하지 않는 부분은 입니다 $15< date -d '$14 1 month'
. 주요 문제는 MM-DD-YYYY 형식이며 두 필드를 비교하고 있습니다.
입력(헤더가 없으며 예시 데이터를 설명하는 데 도움이 되도록 사용합니다.용감한기록된 이유 제외):
.....|field14|field15|.....|Field61|.....
1.....|10-21-2016|11-이십 삼-2016|.....|2016년 10월 25일|.....
2.....|2016년 10월 21일|2016년 11월 20일|.....|11-2016년 2월 25일|.....
3.....|2016년 10월 21일|2016년 11월 19일|.....|2016년 10월 25일|.....
4... ..|2016년 10월 15일|2016년 10월 11일|.....|2016년 10월 25일|.....
5.....|2016년 10월 21일|10~19일-2016|.....|2016-10-25|.....
6.....|09-21-2016|09-19-2016|.....|10-25-2016|.....
필수 출력(제목은 설명용임):
.....|field14|field15|. ...|Field61|.....
3.....|2016년 10월 21일|2016년 11월 19일|.....|2016년 10월 25일|....
4.. ... |2016년 10월 21일|2016년 11월 15일|.....|2016년 10월 25일|.....
이 문제를 어떻게 해결할 수 있나요?
답변1
perl -F'[|]' -lane '
($m2, $d2, $y2, $m1, $d1, $y1) = map { split /-/ } @F[14,13];
($m2, $d2, $y2, $m1, $d1, $y1) =
($m1, $d1, $y1, $m2, $d2, $y2) if !($y2 > $y1 or $m2 > $m1 or $d2 > $d1);
print if
2 == grep /^10-\d{2}-\d{4}$/, @F[13,60]
and
(((12*($y2-$y1)+$m2-$m1) == 1 && ($d2 < $d1))
||
((12*($y2-$y1)+$m2-$m1) == 0))
' yourfile
설명하다
암시적 줄 읽기 루프를 설정하고 파이프 "|"를 사용하여 읽은 각 줄을 분할하여 @F
구분 기호와 인덱스로 시작하는 배열을 만듭니다.0
그런 다음 나중에 코드에서 쉽게 조작할 수 있도록 필드의 월/년/일 정보를 스칼라 변수 14
에 채웁니다.15
이 작업을 수행할 때 날짜 논리 계산을 단순화하기 위해 m2y2d2
날짜가 항상 날짜보다 최신이 되도록 약간 조정합니다 .m1y1d1
마지막으로 우리는 다음 4가지 기준에 따라 현재 레코드, 즉 행의 인쇄를 판단하기로 결정했습니다.
- 14번째 요소는
$F[13]
월October
과 일입니다. 그리고 - 61번째 요소, 즉 해당 월의 날짜
$F[60]
이기도 합니다 .October
그리고 - 두 날짜는 연도를 고려한 용어를 사용하여 한 달 간격
(y2-y1)*12
이며, 상위 날짜의 날짜 < 하위 날짜의 날짜인 경우 서로 월 내에 있습니다. 또는 - 이 두 날짜는 같은 연도와 월에 있습니다 => 어쨌든 둘 다 한 달 내에 있습니다.
답변2
각 줄에 대해 이를 실행하는 것은 date
매우 비효율적이며 날짜 계산을 직접 수행할 수 있는 텍스트 처리 도구를 사용하는 것이 더 나을 것입니다 perl
. 예를 들면 다음과 같습니다.
perl -MTime::Piece -F'[|]' -lane 'print if
$F[13] =~ /10-..-2016/ &&
$F[60] =~ /10-..-2016/ &&
Time::Piece->strptime($F[14], "%m-%d-%Y") <
Time::Piece->strptime($F[13], "%m-%d-%Y")->add_months(1)' file
답변3
GNU awk
실제로 시간 함수가 내장된 를 사용하면 그리 어렵지 않습니다 .
$2 ~ /^10/ && $5 ~ /^10/ {
split($2, t, "-");
t1 = mktime(t[3] " " t[1] " " t[2] " 0 0 0");
split($3, t, "-");
t2 = mktime(t[3] " " t[1] " " t[2] " 0 0 0");
if (t2 >= t1 && t2 - t1 <= 30*24*3600) {
print;
}
}