GNU/Linux >> Linux の 問題 >  >> Linux

5つの実用的な例で説明されたAWK配列

Awk プログラミング言語は配列をサポートします。進行中の awk の例シリーズの一部として、awk ユーザー定義変数と awk 組み込み変数を見てきました。配列は変数の拡張です。配列は、複数の値を保持する変数です。変数と同様に、配列にも名前があります。一部のプログラミング言語では、配列にメモリが割り当てられるように、配列を宣言する必要があります。また、配列インデックスは通常、array[1]、array[2] などのように整数です。

Awk 連想配列

Awk は連想配列のみをサポートします。連想配列は、数値ではなく文字列をインデックスとして使用する点を除いて、従来の配列と似ています。連想配列を使用する場合、数値文字列をインデックスとして使用することで、従来の配列を模倣できます。

Syntax:

arrayname[string]=value

上記の awk 構文では:

  • 配列名 配列の名前です。
  • 文字列 配列のインデックスです。
  • 価値 配列の要素に割り当てる任意の値です。

AWK 配列の要素へのアクセス

配列内の特定の要素にアクセスする場合は、そのインデックス — arrayname[index] を介してアクセスできます。これにより、そのインデックスに割り当てられた値が得られます。

すべての配列要素にアクセスしたい場合は、以下に示すように、ループを使用して配列のすべてのインデックスを調べることができます。

Syntax:

for (var in arrayname)
actions

上記の awk 構文では:

  • var 任意の変数名です
  • はキーワードです
  • 配列名 配列の名前です。
  • アクション 実行するステートメントのリストです。複数のアクションを実行する場合は、中かっこで囲む必要があります。

このループは、変数 var がそのインデックスに設定された配列のインデックスとして使用されたそれぞれの異なる値に対してアクションのリストを実行します。

AWK 配列から要素を削除する

配列の特定のインデックスの要素を削除する場合は、awk delete ステートメントを使用します。 awk 配列から要素を削除すると、その値を取得できなくなります。

Syntax:

delete arrayname[index];

以下のループ コマンドは、配列からすべての要素を削除します。配列からすべての要素を削除する単一のステートメントはありません。ループを通過し、awk delete ステートメントを使用して各配列要素を削除する必要があります。

for (var in array)
     delete array[var]

5 つの実用的な awk 配列の例

以下に示すすべての例では、以下に示す Iplogs.txt ファイルを使用しています。このサンプル テキスト ファイルには、ゲートウェイ サーバーによって要求された IP アドレスのリストが含まれています。この Iplogs.txt ファイルのサンプルには、次の形式のデータが含まれています:

[date] [time] [ip-address] [number-of-websites-accessed]
$ cat Iplogs.txt
180607 093423	123.12.23.122 133
180607 121234	125.25.45.221 153
190607 084849   202.178.23.4 44
190607 084859   164.78.22.64 12
200607 012312	202.188.3.2 13
210607 084849   202.178.23.4 34
210607 121435	202.178.23.4 32
210607 132423	202.188.3.2 167

例 1. すべての一意の IP アドレスと、それが要求された回数を一覧表示する

$ awk '{
> Ip[$3]++;
> }
> END{
> for (var in Ip)
> print var, "access", Ip[var]," times"
> }
> ' Iplogs.txt
125.25.45.221 access 1  times
123.12.23.122 access 1  times
164.78.22.64 access 1  times
202.188.3.2 access 2  times
202.178.23.4 access 3  times

上記のスクリプトでは:

  • 3 番目のフィールド ($3) は IP アドレスです。これは、Ip という配列のインデックスとして使用されます。
  • 行ごとに、対応する IP アドレス インデックスの値を増やします。
  • 最後の END セクションでは、すべてのインデックスが一意の IP アドレスのリストになり、それに対応する値が出現回数になります。

例 2. すべての IP アドレスを一覧表示し、アクセスしたサイトの数を計算する

Iplogs.txt の最後のフィールドは、特定の日時に各 IP アドレスがアクセスしたサイトの数です。以下のスクリプトは、IP アドレスのリスト、ゲートウェイを要求した回数、およびアクセスしたサイトの総数を含むレポートを生成します。

$cat ex2.awk
BEGIN {
print "IP Address\tAccess Count\tNumber of sites";
}
{
Ip[$3]++;
count[$3]+=$NF;
}
END{
for (var in Ip)
	print var,"\t",Ip[var],"\t\t",count[var];
}

$ awk -f ex2.awk Iplogs.txt
IP Address	Access Count	Number of sites
125.25.45.221 	 1 		 153
123.12.23.122 	 1 		 133
164.78.22.64 	 1 		 12
202.188.3.2 	 2 		 180
202.178.23.4 	 3 		 110

上記の例では:

  • 2 つの配列があります。両方の配列のインデックスは同じです — これは IP アドレス (3 番目のフィールド) です。
  • 「Ip」という名前の最初の配列には、一意の IP アドレスとその出現回数のリストがあります。 「count」と呼ばれる 2 番目の配列にはインデックスとして IP アドレスがあり、その値は最後のフィールド (サイトの数) になるため、IP アドレスが来るたびに最後のフィールドを追加し続けます。
  • END セクションでは、すべての IP アドレスを調べて、Ip という配列から IP アドレスとアクセス数を出力し、配列カウントからサイト数を出力します。

例 3. 最大アクセス日を特定する

$ cat ex3.awk
{
date[$1]++;
}
END{
for (count in date)
{
	if ( max < date[count] ) {
		max = date[count];
		maxdate = count;
	}

}
print "Maximum access is on", maxdate;
}

$ awk -f ex3.awk Iplogs.txt
Maximum access is on 210607

この例では:

  • 「date」という名前の配列は、インデックスとして日付を持ち、配列の値として出現回数を持ちます。
  • max は、カウント値を持つ変数であり、最大カウントを持つ日付を見つけるために使用されます。
  • maxdate は、カウントが最大になる日付を持つ変数です。

例 4. ファイル内の行の順序を逆にする

$ awk '{ a[i++] = $0 } END { for (j=i-1; j>=0;) print a[j--] }' Iplogs.txt
210607 132423	202.188.3.2 167
210607 121435	202.178.23.4 32
210607 084849   202.178.23.4 34
200607 012312	202.188.3.2 13
190607 084859   164.78.22.64 12
190607 084849   202.178.23.4 44
180607 121234	125.25.45.221 153
180607 093423	123.12.23.122 133

この例では、

  • 配列「a」のすべての行を記録することから始めます。
  • プログラムがすべての行の処理を終了すると、Awk は END { } ブロックを実行します。
  • END ブロックは、配列「a」の要素をループし、記録された行を逆の方法で出力します。

例 5. awk を使用して重複行や連続していない行を削除する

$ cat > temp
foo
bar
foo
baz
bar

$ awk '!($0 in array) { array[$0]; print }' temp
foo
bar
baz

この例では:

  • Awk はファイル「temp」からすべての行を読み取り、「in」演算子を使用して、現在の行が配列「a」に存在するかどうかをチェックします。
  • 存在しない場合は、現在の行を保存して出力します。

推奨読書

<強い> Ramesh Natarajan による Sed と Awk の 101 ハック .テキスト ファイル (データ、構成、およびログ ファイル) を扱う UNIX/Linux 環境で、1 日に数時間を費やしています。私はすべてのテキスト操作作業に Sed と Awk を使用しています。私の Sed と Awk の経験に基づいて、Sed と Awk のさまざまな高度な機能に関する 101 の実用的な例を含む Sed and Awk 101 Hacks eBook を書きました。これにより、UNIX/Linux の生活が向上します。 Sed と Awk を数年間使用しており、この本を読んでいない場合でも、ぜひこの本を読んでください。 Sed および Awk ユーティリティの機能に驚かれることでしょう。


Linux
  1. Linuxのshutdownコマンドを例で説明

  2. 例を含む Bash 配列

  3. 実際の例を含むエコーコマンド

  1. Linux Tracerouteコマンド、例を使用して説明

  2. Awk チュートリアル:3 つの実践例で Awk 変数を理解する

  3. Perl 配列参照と逆参照のチュートリアルと実践例

  1. Linuxカットコマンドを6つの例で説明

  2. LinuxでのAWKコマンドと例

  3. Linuxのlddコマンドを例で説明