awkには最大値を算出する関数は用意されていないので、自作する必要がありました。
フィールド(列)を指定した最大値算出は、データ処理にとても便利なので、使っていくとどんどん世界が広がります。

スポンサーリンク

サンプルコード

※awkの使い方をまとめて一覧にしました。
参考:awk入門-使い方まとめ一覧-

まずはサンプルコードです。
in.txtの4フィールド目(4列目)の最大値を算出しています。
sample.awkを実行すると、最大値が算出されています。

 $ cat in.txt 
2015 1 1 -4
2015 1 2 89
2015 1 3 99
2015 1 1 -4
2016 1 2 89
2016 1 3 99
2017 1 1 -4
2017 1 2 89
2017 1 3 99

 $ cat sample.awk 
#!/bin/sh
cat in.txt | awk '		
	BEGIN{
		count = 0
	}
	{
 	   	year = $1
		month = $2
		day = $3
		val = $4
		
		if(count == 0){
			max = val #初期値を設定
			print "初期値を設定 max=" max
			count++
		}
		if(val > max){
			max = val #最大値を更新
			print "最大値を更新 max=" max			
		}
	}
	END{
		print "最大値=" max
	}
'

 $ ./sample.awk 
初期値を設定 max=-4
最大値を更新 max=89
最大値を更新 max=99
最大値=99

いくつかポイントを下記に解説してみます。

スポンサーリンク

まずは初期値の設定を慎重にすることが大事

まずは初期値を変数maxに設定します。

初期値の設定方法は色々とあると思います。
今回採用した方法は、1行目を読み込んだら初期値として設定する方法です。
カウンターを設けて、カウンターが0の場合は、初期値として設定しました。

BEGINブロックでカウンターを0とし、

	BEGIN{
		count = 0
	}

1行目の処理をした時(カウンターが0の時)に、下記のように初期値を設定しています。

		if(count == 0){
			max = val #初期値を設定
			print "初期値を設定 max=" max
			count++
		}

NR変数は使用していません。
NR変数で1行目を判定するのもありだと思いますが、最大値を算出するレコード(行)の範囲を変更した場合(1行目を最大値の算出対象としなかった場合)には、初期値の設定がされなくなってしまいます。

1行ずつ読み込んで、最大値を更新していく

あとは、1行ずつ読み込んで、変数maxの値と取得したフィールド(列)の値を比較して、
変数maxより大きければ変数maxを更新する基本的な計算方法です。

		if(val > max){
			max = val #最大値を更新
			print "最大値を更新 max=" max			
		}

最大値の更新が終了したら、ENDブロックで最大値を出力

全ての行の読み込んが終了して最大値の更新が終了したら、最大値を出力します。
ENDブロックで最大値を出力すればOK。

	END{
		print "最大値=" max
	}

スポンサーリンク