awkには、連想配列として配列が用意されていますが、pythonやperlのように配列操作が充実してないですよね。
特に、unshift・shift・push・pop関数に関しては、あるとほんと便利なので、自作して使いまわしています。
下記に紹介してみたいと思います(あくまで自作なので、本来のunshift・shift・push・pop関数と異なる場合があるのはご了承ください)。
スポンサーリンク
サンプルコード
参考:awk入門-使い方まとめ一覧-
unshift・shift・push・pop関数を、それぞれユーザー定義関数としてunshiftArr()・shiftArr()・pushArr()・popArr()を定義しています。in.txtを一行ずつ読み込んで、unshiftArr()をcallして1フィールド(列)目を配列の先頭に詰めていきます。その後、ENDブロックで、unshiftArr()・shiftArr()・pushArr()・popArr()を順に実行しています。
例えば、下記のin.txtがあったとします。
$ cat in.txt e f g h i
下記がサンプルコードになります。
$ cat sample.awk #!/bin/sh cat in.txt | awk ' { unshiftArr(arrF1, $1) } END{ print "" print "unshift操作" unshiftArr(arrF1, "2") print "" print "shift操作" shiftArr(arrF1) print "" print "push操作" pushArr(arrF1, "2") print "" print "pop操作" popArr(arrF1) popArr(arrF1) popArr(arrF1) popArr(arrF1) popArr(arrF1) popArr(arrF1) popArr(arrF1) delete arrF1 print "" print "unshift操作" unshiftArr(arrF2, 3) print "unshift操作" shiftArr(arrF2) shiftArr(arrF2) delete arrF2 } #print関数 function printArr(arr) { if(length(arr) == 0){ print "Empty" return } for (i = 0; i < length(arr); i++ ) { printf "%s," , arr[ i ] } print "" } #unshift関数 function unshiftArr(arr, inStr ) { for(i = length(arr); i > 0 ; i-- ) { arr[ i ] = arr[ i - 1 ] } arr[ 0 ] = inStr #index=0にinStrを入力 printArr(arr) } #shift関数 function shiftArr(arr) { if(length(arr) == 0){ print "Empty" return } for(i = 0; i < length(arr) - 1 ; i++ ) { arr[ i ] = arr[ i + 1 ] } delete arr[ length(arr) - 1 ] printArr(arr) } #push関数 function pushArr(arr, inStr ) { arr[ length(arr) ] = inStr printArr(arr) } #pop操作 function popArr(arr) { if(length(arr) == 0){ print "Empty" return } delete arr[ length(arr) - 1] printArr(arr) } '
下記が実行結果になります。
$ ./sample.awk e, f,e, g,f,e, h,g,f,e, i,h,g,f,e, unshift操作 2,i,h,g,f,e, shift操作 i,h,g,f,e, push操作 i,h,g,f,e,2, pop操作 i,h,g,f,e, i,h,g,f, i,h,g, i,h, i, Empty Empty unshift操作 3, unshift操作 Empty Empty
スポンサーリンク
awkでunshift関数を自作
unshiftについては下記のようにユーザー定義しています。
実行すると、配列arrの先頭に、文字列instrを入力します。
#unshift関数 function unshiftArr(arr, inStr ) { for(i = length(arr); i > 0 ; i-- ) { arr[ i ] = arr[ i - 1 ] } arr[ 0 ] = inStr #index=0にinStrを入力 printArr(arr) }
awkでshift関数を自作
shiftについては下記のようにユーザー定義しています。
実行すると、配列arrの先頭が削除されます。
#shift関数 function shiftArr(arr) { if(length(arr) == 0){ print "Empty" return } for(i = 0; i < length(arr) - 1 ; i++ ) { arr[ i ] = arr[ i + 1 ] } delete arr[ length(arr) - 1 ] printArr(arr) }
awkでpush関数を自作
pushについては下記のようにユーザー定義しています。
実行すると、配列arrの後尾にinStrが入力されます。
#push関数 function pushArr(arr, inStr ) { arr[ length(arr) ] = inStr printArr(arr) }
awkでpop関数を自作
popについては下記のようにユーザー定義しています。
実行すると、配列arrの後尾が削除されます。
**
空の配列を引数にしたときの挙動について、ご指摘を頂きました。
下記のように、空の場合はreturnするようにして変更いたしました。
引数に設定した時点で空の配列が生成されてしまいますが、生成した配列のdeleteは読び出し側の責務で行うようにと考えました。
また、pop時に値を返していませんが、これは自作した時に必要がなかったので、あえて返していないのが実情です。
本記事の趣旨は自作の関数の紹介なのでこのままにさせてください。
一連のご指摘を頂きました読者様ありがとうございました。
#pop操作 function popArr(arr) { if(length(arr) == 0){ print "Empty" return } delete arr[ length(arr) - 1] printArr(arr) }
スポンサーリンク