ウェブサイト検索

Awk の特別なパターン「BEGIN と END」の使用方法を学ぶ – パート 9


この Awk シリーズのパート 8 では、変数、数値式、代入演算子などの強力な Awk コマンド機能をいくつか紹介しました。

このセグメントでは、さらに多くの Awk 機能、つまり特別なパターンである BEGINEND について説明します。

これらの特別な機能は、 複雑なAwk オペレーションを構築する方法をさらに拡張して探索するときに役立つことがわかります。

まず、Awk シリーズの紹介に考えを戻しましょう。このシリーズを開始したときに、Awk を実行するための一般的な構文は次のとおりであると指摘したことを思い出してください。 > コマンドは次のとおりです。

awk 'script' filenames  

上記の構文では、Awk スクリプトの形式は次のとおりです。

/pattern/ { actions } 

スクリプト内のパターンを考慮する場合、通常は正規表現ですが、パターンを特別なパターン BEGIN および END として考えることもできます。したがって、 以下の形式でAwk コマンドを記述することもできます。

awk '
 	BEGIN { actions } 
 	/pattern/ { actions }
 	/pattern/ { actions }
            ……….
	 END { actions } 
' filenames  

Awk スクリプトで BEGINEND という特殊なパターンを使用する場合、それぞれの意味は次のとおりです。

  1. BEGIN パターン: 入力行が読み取られる前に、Awk が BEGIN で指定されたアクションを 1 回実行することを意味します。
  2. END パターン: Awk が実際に終了する前に、END で指定されたアクションを実行することを意味します。

これらの特別なパターンを含むAwk コマンド スクリプトの実行フローは次のとおりです。

  1. BEGIN パターンがスクリプトで使用されている場合、BEGIN のすべてのアクションは、入力行が読み取られる前に 1 回実行されます。
  2. 次に、入力行が読み取られ、さまざまなフィールドに解析されます。
  3. 次に、指定された非特殊パターンのそれぞれが入力行と比較され、一致するものが見つかると、そのパターンのアクションが実行されます。この段階は、指定したすべてのパターンに対して繰り返されます。
  4. 次に、ステージ 2 と 3 がすべての入力ラインに対して繰り返されます。
  5. すべての入力行が読み取られて処理されると、END パターンを指定した場合、アクションが実行されます。

Awk 操作で最良の結果を得るために特別なパターンを使用するときは、この実行シーケンスを常に覚えておく必要があります。

すべてを理解するために、domains.txt という名前のファイルに保存されている、Tecmint が所有するドメインのリストに関するパート 8 の例を使用して説明しましょう。

news.linux-console.net
linux-console.net
linuxsay.com
windows.linux-console.net
linux-console.net
news.linux-console.net
linux-console.net
linuxsay.com
linux-console.net
news.linux-console.net
linux-console.net
linuxsay.com
windows.linux-console.net
linux-console.net
cat ~/domains.txt

この例では、ドメイン linux-console.net がファイル domains.txt にリストされている回数をカウントしたいと考えています。そこで、変数、数値式、代入演算子の考え方を使用して、これを行うのに役立つ次の内容の小さなシェル スクリプトを作成しました。

#!/bin/bash
for file in $@; do
        if [ -f $file ] ; then
                #print out filename
                echo "File is: $file"
                #print a number incrementally for every line containing linux-console.net 
                awk '/^linux-console.net/ { counter+=1 ; printf "%s\n", counter ; }' $file
        else
                #print error info incase input is not a file
                echo "$file is not a file, please specify a file." >&2 && exit 1
        fi
done
#terminate script with exit code 0 in case of successful execution 
exit 0

次に、次のように、上記のスクリプトの Awk コマンドで 2 つの特別なパターン、BEGINEND を使用してみましょう。

スクリプトを変更します。

awk '/^linux-console.net/ { counter+=1 ; printf "%s\n", counter ; }' $file

に :

awk ' BEGIN {  print "The number of times linux-console.net appears in the file is:" ; }
                      /^linux-console.net/ {  counter+=1  ;  }
                      END {  printf "%s\n",  counter  ; } 
                    '  $file

Awk コマンドに変更を加えた後、完全なシェル スクリプトは次のようになります。

#!/bin/bash
for file in $@; do
        if [ -f $file ] ; then
                #print out filename
                echo "File is: $file"
                #print the total number of times linux-console.net appears in the file
                awk ' BEGIN {  print "The number of times linux-console.net appears in the file is:" ; }
                      /^linux-console.net/ {  counter+=1  ;  }
                      END {  printf "%s\n",  counter  ; } 
                    '  $file
        else
                #print error info incase input is not a file
                echo "$file is not a file, please specify a file." >&2 && exit 1
        fi
done
#terminate script with exit code 0 in case of successful execution 
exit 0

上記のスクリプトを実行すると、まずファイル domains.txt の場所が出力され、次に Awk コマンド スクリプトが実行されます。 特別なパターンは、ファイルから入力行が読み取られる前に、「ファイル内に linux-console.net が表示される回数: 」というメッセージを出力するのに役立ちます。

次に、パターン /^linux-console.net/ がすべての入力行とアクション { counter+=1 ; と比較されます。 } は入力行ごとに実行され、ファイル内に linux-console.net が出現する回数がカウントされます。

最後に、END パターンは、ファイル内にドメイン linux-console.net が出現する合計回数を出力します。

./script.sh ~/domains.txt 

結論として、特別なパターン BEGINEND の概念を検討しながら、さらに多くの Awk 機能について説明しました。

以前に指摘したように、これらの Awk 機能は、より複雑なテキスト フィルタリング操作を構築するのに役立ちます。Awk 機能ではさらに詳しく説明します。パート 10 では、 Awk の組み込み変数のアイデアなので、接続を維持してください。