awkでは配列は用意されていますが、pythonやperlのように、配列の操作が柔軟にできないのが物足りないところです。

unshiftで配列の先頭に値を追加できるようになるとawkの利便性がぐっとあがると思い(必要に迫られたというのもあります)、自作してみました。

あくまで自作なので、一般的なunshiftとは異なる箇所があったりすることは、ご了承ください。
例えば、配列のインデックスは0~9に制約を設定して、unshiftをすると最後尾の要素が切り捨てられます。
※要素数に制約を設けない関数も自作してみましたので、後ほど追記したいと思います。
→追記しました。[Linux]awkでunshift・shift・push・pop関数が用意されていないので、自作して使っています

ただし、この関数が自作したおかげで、個人的にはプログラミングの効率がぐっとあがりました。
配列の要素に上限を設けたのも、自分の使い方の要件と合致していて、簡単な実装ながら利便性は高く重宝しています。

スポンサーリンク

サンプルコード

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

unshiftArrという関数を定義しました。

ただし、格納できる配列のインデックスを0~9と設定し、
unshiftを実行するとindex=9の要素は切り捨てられます。

in.txtを一行ずつ読み込んで、1フィールド(列)目をunshiftArr()関数を使って、順にarrF1の先頭に詰めていきます。
全てのレコード(行)の処理が終わると、ENDブロックで"2"をunshiftArr()関数を使って先頭に詰めています。

 $ cat in.txt 
a
b
c
d
e
f
g
h
i
j
k
l
m

 $ cat sample.awk 
#!/bin/sh
cat in.txt | awk '		
	{
 	   	unshiftArr( arrF1, $1)
	}
	END{
		for (i = 0; i < 10; i++ ) {
			printf "%s," , arrF1[ i ]
		}
		print ""
		unshiftArr( arrF1, "2")		
		for (i = 0; i < 10; i++ ) {
			printf "%s," , arrF1[ i ]
		}
	}
	#格納できる配列のインデックスを0~9と想定
	#本関数を実行すると、index=9の要素は切り捨てられ、index=0の要素に値が入る
	function unshiftArr( arr, inStr ) {
		for(i = 9; i > 0 ; i-- ) {
			arr [ i ] = arr[ i -1 ]			
		}
		arr[ 0 ] = inStr #index=0にinStrを入力
	}
'

 $ ./sample.awk 
m,l,k,j,i,h,g,f,e,d,
2,m,l,k,j,i,h,g,f,e,

スポンサーリンク

unshiftArr関数をユーザー定義関数として定義

ユーザー定義関数を下記のように定義しています。

	#格納できる配列のインデックスを0~9と想定
	#本関数を実行すると、index=9の要素は切り捨てられ、index=0の要素に値が入る
	function unshiftArr( arr, inStr ) {
		for(i = 9; i > 0 ; i-- ) {
			arr [ i ] = arr[ i -1 ]			
		}
		arr[ 0 ] = inStr #index=0にinStrを入力
	}

下記のように、ENDブロックで"2"をunshiftしていますが、

	END{
          〜省略〜
		unshiftArr( arrF1, "2")		
          〜省略〜
	}

下記のように、実行すると"2"が先頭に入力されていて、最後尾が切り捨てられるいるのがわかると思います。

 $ ./sample.awk 
m,l,k,j,i,h,g,f,e,d,
2,m,l,k,j,i,h,g,f,e,

配列の要素数を無限にする関数を実装することも考えましたが、
何より自分の実装要件では要素数に上限を設けた方が利便性が高かったことと、
その方が関数の実装も楽だったのでこのような制約を設けました。

スポンサーリンク