awkコマンドにタイムスタンプを含める

awkコマンドにタイムスタンプを含める

ほぼ同じCSVファイルを検討してください。それらはすべて共通して1行とDate;Time;...4つのデータ列を持っています。一部は最初の行に6つの列があります。ここで、5番目の列は空で、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つのスクリプトに結合する方法はありますか?現在、これらは2つの別々のシステムで実行されています。

答え1

2つの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

これは、GNUawkまたはmawk(またはawk実装しない可能性があるBSDではない)を使用していると仮定します。mktime()strftime()

コードは2つの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}

関連情報