24

awkには連想配列があることはわかっていますが、これに相当するawkがあるのではないかと思います。

http://php.net/manual/en/function.array-push.php

明らかな回避策は、次のように言うことです。

array[$new_element] = $new_element

ただし、これは必要以上に読みにくく、ハックっぽいようです。

4

3 に答える 3

20

配列の長さがawkですぐに利用できるとは思いません(少なくとも、私がいじっているバージョンではそうではありません)。ただし、単純に長さを維持してから、次のようにすることもできます。

array[arraylen++] = $0;

そして、同じ整数値を介して要素にアクセスします。

for ( i = 0; i < arraylen; i++ )
   print array[i];
于 2012-05-25T18:08:57.617 に答える
12

gawk配列の長さを見つけることができるlength(var)ので、独自の関数を作成するのはそれほど難しくありません。

function push(A,B) { A[length(A)+1] = B }

ただし、この議論に注意してください。当たり前。しかし、これは概算です。

vnix$ gawk '# BEGIN: make sure arr is an array
>   BEGIN { delete arr[0] }
>   { print "=" length(arr); arr[length(arr)+1] = $1;
>     print length(arr), arr[length(arr)] }
>   END { print "---";
>     for (i=1; i<=length(arr); ++i) print i, arr[i] }' <<HERE
> fnord foo
> ick bar
> baz quux
> HERE
=0
1 fnord
=1
2 ick
=2
3 baz
---
1 fnord
2 ick
3 baz
于 2012-05-25T18:11:15.530 に答える
3

他の人が言ったように、 awk はそのままではこのような機能を提供しません。「ハック」の回避策は、一部のデータセットでは機能する場合がありますが、他のデータセットでは機能しない場合があります。同じ配列値を 2 回追加する可能性があり、それを配列内で 2 回表現したいと考えてください。

$ echo 3 | awk 'BEGIN{ a[1]=5; a[2]=12; a[3]=2 }
>   { a[$1] = $1 }
>   END {print length(a) " - " a[3]}'
3 - 3

最良の解決策は、配列内のデータによって通知される場合がありますが、いくつかの考えがあります。

まず、インデックスが常に数値であり、常に 1 から始まり、配列要素を削除しないことが確実な場合は、トリプルの提案がうまくいくA[length(A)+1]="value"可能性があります。ただし、要素を削除すると、次の書き込みで最後の要素が上書きされる可能性があります。

インデックスが問題ではなく、長いキーでスペースを浪費する心配がない場合は、衝突の可能性を減らすのに十分な長さの乱数を使用できます。クイック&ダーティなオプションは次のとおりです。

srand()
a[rand() rand() rand()]="value"

ランダム化を改善するために使用することを忘れないでください。実際の乱数を生成することをsrand()信頼しないでください。rand()これは多くの点で完璧とは言えませんが、1 行のコードで済むという利点があります。

キーが数値であるが sparseの可能性がある場合、トリプルのソリューションを壊す例のように、プッシュ関数に小さな検索を追加できます。

function push (a, v,     n) {
  n=length(a)+1
  while (n in a) n++
  a[n]=v
}

while ループにより、未使用のインデックスが確実に割り当てられます。この関数は、数値以外のインデックスを使用する配列とも互換性があります。数値のキーを割り当てますが、既に存在するものは気にしません。

awk は配列内の要素の順序を保証しないことに注意してください。そのため、「項目を配列の最後にプッシュする」という考えは間違っています。この要素を配列に追加しますが、forループを実行するときに最後に表示されるという保証はありません。

$ cat a
#!/usr/bin/awk -f

function push (a, v,     n) {
  n=length(a)+1
  while (n in a) n++
  a[n]=v
}

{
  push(a, $0)
}

END {
  print "length=" length(a)
  for(i in a) print i " - " a[i]
}

$ printf '3\nfour\ncinq\n' | ./a
length=3
2 - four
3 - cinq
1 - 3
于 2016-08-29T06:32:25.953 に答える