awk 명령에 타임스탬프 포함

awk 명령에 타임스탬프 포함

거의 동일한 CSV 파일을 고려하십시오. 그들은 모두 공통적으로 한 행과 Date;Time;...4개의 데이터 열을 가지고 있습니다. 일부는 첫 번째 행에 6개의 열이 있는데, 여기서 다섯 번째 열은 비어 있고 여섯 번째 열은 설명 텍스트입니다. 행 앞에는 열로 구분된 설명 텍스트가 옵니다.Date;Time;...

...
...
Date;Time;Airtemp;Quality;;Other info
1961-01-01;06:00:00;0.4;G;;...
1961-01-01;12:00:00;2.3;G;;...
1961-01-01;18:00:00;...;.;;...
1961-01-02;15:00:00;...;.  
..........;........;...;.
2015-09-01;........;...;.

다음 명령을 사용하십시오 (*)

awk -F ';' 'x==1 {print $1 " " $2 " " $3 " " $4} /Date/ {x=1}' file >> new_file

sed -i '' 's/[-:,]//g' new_file

만들기new_file

19610101   060000  0.4  G 
19610101   120000  2.3  G 
19610101   180000  ...  . 
19610102   150000  ...  .        
19610102   180000  ...  .       
19610103   060000  ...  .      
........   ......  ...  .
20150901   ......  ...  .

이제 (**) 명령을 사용하십시오.

awk '
     {
        tspec = sprintf("%4d %.2d %.2d 00 00 00", substr($1,1,4), substr($2,1,2), substr($2,3,4))
        t = mktime(tspec)
        $(NF+1) = 0 + strftime("%j",t)
    } {print}' new_file

다른 열을 만들고 new_file일수를 포함합니다.

19610101   060000  0.4  G 1
19610101   120000  2.3  G 1
19610101   180000  ...  . 1
19610102   150000  ...  . 2
19610102   180000  ...  . 2
19610103   060000  ...  . 3
........   ......  ...  . .
20150901   ......  ...  . .

(*)와 (**) 명령을 하나의 스크립트에 결합하는 방법이 있나요? 현재 이들은 두 개의 별도 시스템에서 실행됩니다.

답변1

awk명령을 결합합니다(및 sed):

awk -F ';' '
    x == 1 {
        gsub("[:,-]", "")
        tspec = sprintf("%4d %.2d %.2d 00 00 00", substr($1,1,4), substr($1,5,2), substr($1,7,4))
        t = mktime(tspec)
        print $1, $2, $3, $4, 0 + strftime("%j", t)
    }
    /Date/ { x = 1 }' file

이는 GNU awk또는 mawk( 또는 awk을 구현하지 않을 수 있는 BSD가 아님 )을 사용하고 있다고 가정합니다.mktime()strftime()

코드는 두 개의 awk명령 및 sed(을 사용하여 gsub())을 결합했으며, 설정된 날짜의 구문 분석을 자유롭게 수정했습니다 tspec.

파일이 주어지면,

...
...
Date;Time;Airtemp;Quality;;Other info
1961-01-01;06:00:00;0.4;G;;...
1961-01-01;12:00:00;2.3;G;;...
1961-01-01;18:00:00;...;.;;...
1961-01-02;15:00:00;...;.
2015-09-01;........;...;.

이것은 생산할 것입니다

19610101 060000 0.4 G 1
19610101 120000 2.3 G 1
19610101 180000 ... . 1
19610102 150000 ... . 2
20150901 ........ ... . 244

공백은 기본 출력 필드 구분 기호( OFS)이므로 명시적으로 아무것도 설정하지 않으면 각 출력 필드 사이에 공백을 두고 출력할 OFS필요가 없습니다(해서는 안 됩니다) ." "

답변2

이 질문은 실제 데이터를 보여주지 않았기 때문에 대답하기 어렵습니다. 그러나 내가 올바르게 이해했다면 타임스탬프를 전혀 고려할 필요가 없습니다. 원하는 출력에 따라 입력에서 합계를 제거 -하고 추가 열을 추가하면 됩니다.:

$ awk -F';' '{day=substr($1,9,2); gsub(/[:-]/,""); printf "%s;%.1d\n",$0,day}' file
19610101;060000;0.4;G;...;1
19610101;120000;2.3;G;...;1
19610101;180000;...;.;1
19610102;150000;...;.  ;2
..........;........;...;.;0
20150901;........;...;.;1

또는 원하는 출력에 탭으로 구분된 열을 표시하려는 경우:

 $ awk -F';' -vOFS="\t" '{day=substr($1,9,2); gsub(/[:-]/,""); print $1,$2,$3,$4, sprintf("%.1d",day)}' file
19610101    060000  0.4 G   1
19610101    120000  2.3 G   1
19610101    180000  ... .   1
19610102    150000  ... .   2
..........  ........    ... .   0
20150901    ........    ... .   1

답변3

올해의 날짜를 표시하려면 $4를 $5로 변경해 보세요.

{print $1 " " $2 " " $3 " " $4}

관련 정보