以前下記の記事で紹介した応用編です。
[Linux]awkでフィールド(列)の最大値を求める
単に1列全てを最大値算出の対象にするのではなく、条件によって算出対象を絞ります。

スポンサーリンク

あるフィールド(列)の文字列で、対象レコード(行)を指定

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

メインブロックの条件部に、1フィールド(列)目の条件を追加

下記のように、1フィールド(列)目が2017であれば、そのレコード(行)の処理を実行するように、
条件部を設定しています。$1は、処理中のレコード(行)の1フィールド(列)目の値になります。

	$1 == 2017{
      〜省略〜
	}

これで、1フィールド(列)目の値が2017の場合のみ、最大値の更新処理が行われます。
例えば、上記のin.txtの例なら、2017年を対象とした、最大値が算出できます。

サンプルコード

in.txtの1フィールド(列)目の文字列が2017の場合にのみ、最大値更新の処理を実行します。

$ cat in.txt 
2015 1 1 -4
2015 1 2 89
2015 1 3 99
2015 1 1 -3
2016 1 2 8
2016 1 3 94
2017 1 1 -5
2017 1 2 85
2017 1 3 97

 $ cat sample.awk 
#!/bin/sh
cat in.txt | awk '		
	BEGIN{
		count = 0
	}
	$1 == 2017{
 	   	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=-5
最大値を更新 max=85
最大値を更新 max=97
最大値=97

スポンサーリンク

NR変数で対象レコード(行)を指定

メインブロックの条件部に、NR変数を使って条件を追加

NR変数で処理中のレコード(行)の値が取得できます。
下記のように条件部を設定することで、2レコード(行)目から6行目の処理が実行できます。

		2 <= NR && NR <= 6{
		print NR "レコード(行)目を処理"
          〜省略〜
	}

こういった条件部を設定することで、データ解析の幅がぐっと広がるので、プログラミングがより面白くなると思います。
レコード(行)の範囲を指定して処理範囲を簡単に変えることができるのは、awkの醍醐味と言えると思います。
より具体的なデータの可視化は、人間の理解を圧倒的に深めますし、発想が広がります。

サンプルコード

in2.txtの2レコード(行)から6レコード(行)までを処理対象とし、最大値を算出しています。

 $ cat in2.txt 
2015 1 1 -4
2015 1 2 89
2015 2 3 91
2015 2 1 -3
2016 1 2 8
2016 1 3 94
2017 1 1 -5
2017 1 2 85
2017 1 3 97

 $ cat sample2.awk 
#!/bin/sh
cat in2.txt | awk '		
	BEGIN{
		count = 0
	}
	2 <= NR && NR <= 6{
		print NR "レコード(行)目を処理"
		
 	   	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
	}
'

 $ ./sample2.awk 
2レコード(行)目を処理
初期値を設定 max=89
3レコード(行)目を処理
最大値を更新 max=91
4レコード(行)目を処理
5レコード(行)目を処理
6レコード(行)目を処理
最大値を更新 max=94
最大値=94

スポンサーリンク