Go to the first, previous, next, last section, table of contents.

すべての配列の要素のスキャン

配列を使うプログラムでは、配列の各要素に対して、一度実行するループが必要な場合がよくあるでしょう。配列が連続しており添字が正の整数に限定されている他の言語では、これは簡単です。一番大きな添字は配列の長さより1小さいので、すべての有効な添字は、0からその値までカウントすれば発見できます。awkでは、どのような数または文字列でも配列の添字になり得るので、このテクニックは使えません。そのため、awkには配列のスキャンのために特別なfor文があります。

for (var in array)
  body

このループは、プログラムが前にarrayで添字として使った(変数varはその添字に設定されています)、異なる値それぞれに対してbodyを一度実行します。

この形式のfor文を使ったプログラムを次に示します。最初のルールは入力レコードをスキャンし、どの単語が入力中に現れるか(少なくとも一度)を、添字としてその単語を持つ配列usedに1を格納することによって記憶します。2番目のルールはusedの要素をスキャンして、入力中に現れる異なる単語をすべて見つけます。また、長さが11文字以上の単語をそれぞれ表示し、その単語数を表示します。組み込み関数lengthの詳細については、See section 組み込み関数

# Record a 1 for each word that is used at least once.
{
  for (i = 0; i < NF; i++)
    used[$i] = 1
}

# Find number of distinct words more than 10 characters long.
END {
  num_long_words = 0
  for (x in used)
    if (length(x) > 10) {
      ++num_long_words
      print x
  }
  print num_long_words, "words longer than 10 characters"
}

このタイプの例の詳細については、See section サンプルプログラム

配列の要素がこの文によってアクセスされる順番は、awk内部の配列の要素の内部配置によって決定され、それを制御したり変更することはできません。これは、body内の文によって新しい要素がarrayに追加された場合、問題が起こります。forループで、その要素までスキャンできるかどうか予測できません。同様に、ループ内でvarが変更された場合は、おかしな結果になります。このようなことは避けたほうが良いでしょう。


Go to the first, previous, next, last section, table of contents.