次の文書の抜粋を検討してください。
19610101 060000 0.4 G
19610101 120000 2.3 G
19610101 180000 ... .
19610102 150000
19610102 180000
19610103 060000
........ ......
20150901
一番左の列は日付を指定します。 1〜365/366の数字で年の日付を指定する列を挿入するにはどうすればよいですか?
各日付の最後の4桁(たとえば、0101,0102、...)を抽出すると、再帰的で増加する数値シーケンスが得られます。私達はそこからどこに行くか。それとももっと簡単な実装はありますか?
答え1
与えられたファイルのfile
内容
19610101 060000 0.4 G
19610101 120000 2.3 G
19610101 180000 ... .
19610102 150000 ... .
19610102 180000 ... .
19610103 060000 ... .
20150901 ...... ... .
awk
GNUまたはmawk
(およびその両方mktime()
)を使用できますstrftime()
。
awk '
{
tspec = sprintf("%4d %.2d %.2d 00 00 00", substr($1,1,4), substr($1,5,2), substr($1,7,2))
t = mktime(tspec)
$(NF+1) = strftime("%j",t)
} { print }' file
t
これにより、ファイルの最初の列で解析された日付に基づいてUnixタイムスタンプが作成されます(午前0時を使用)。次に、formatを使用してstrftime()
タイムスタンプをフォーマットします%j
。これは、ゼロで埋められた整数で、今年の日付を提供します(参考文献を参照man strftime
)。番号が新しい列に挿入され、次の行が印刷されます。
結果:
19610101 060000 0.4 G 001
19610101 120000 2.3 G 001
19610101 180000 ... . 001
19610102 150000 ... . 002
19610102 180000 ... . 002
19610103 060000 ... . 003
20150901 ...... ... . 244
ゼロパディングを削除するには、を使用します$(NF+1) = 0 + strftime(...)
。
答え2
データが均一な場合、例えば
$ cat file
Date Time
19610101 060000
19610101 120000
19610101 060000
19610102 120000
19610102 060000
19610102 120000
20150901 060000
もしそうなら、Miller(mlr
)は良い選択かもしれません。
$ mlr --pprint --fs " " --repifs put -S '
$Day = strftime(strptime($Date,"%Y%m%d"),"%j")
' file
Date Time Day
19610101 060000 001
19610101 120000 001
19610101 060000 001
19610102 120000 002
19610102 060000 002
19610102 120000 002
20150901 060000 244
-S
無制限のフィールドを文字列型にYYYYmmmdd
変換するために使用されますstrptime
(デフォルトでは整数として解析されます)。