AWK ユーティリティには独自の自己完結型言語が付属しており、Unix/Linux やその他の環境で使用できる最も強力なデータ処理エンジンの 1 つです。このプログラミングおよびデータ操作言語 (その名前は、創設者であるアルフレッド・アホ、ピーター・ワインバーガー、ブライアン・カーニハンの姓の頭文字から取られています) の最大の力は、その人が持っている知識に依存します。これを使用すると、入力ファイルの読み取り、データの並べ替え、データの処理、入力に対する計算の実行、レポートの生成など、無数の機能を実行する短いプログラムを作成できます。
AWKとは何ですか? 最も単純に言えば、AWK はテキストを操作するためのプログラミング言語ツールです。 AWK ユーティリティの言語はシェル プログラミング言語と多くの点で似ていますが、AWK には完全に独自の構文があります。 AWK が作成された当初はテキスト処理を目的としており、入力データにパターンが一致するたびに一連の命令を実行することが言語の基礎でした。このユーティリティは、ファイル内の各行をスキャンして、コマンド ラインで指定されたものと一致するパターンを探します。一致するものが見つかった場合は、次のプログラミング手順に進みます。一致するものが見つからない場合は、次の行の処理を続行します。 操作は複雑になる場合がありますが、コマンドの構文は常に次のとおりです: awk {パターン + アクション} ここで、パターンは AWK がデータ内で検索するものを表し、アクションは一致が見つかったときに実行される一連のコマンドです。中括弧 ({}) はプログラム内で常に使用する必要はありませんが、特定のパターンに従って一連の命令をグループ化するために使用されます。 フィールドについて このユーティリティは、各入力行をレコードとフィールドに分割します。レコードは 1 行の入力であり、各レコードには複数のフィールドが含まれます。デフォルトのフィールド区切り文字はスペースまたはタブ、レコード区切り文字は改行です。デフォルトでは、タブとスペースの両方がフィールド区切り文字として扱われますが (複数のスペースは依然として 1 つの区切り文字として機能します)、区切り文字をスペースから他の文字に変更することができます。 デモのために、emp_names として保存された次の従業員リスト ファイルを表示します。 46012 DULANEY EVAN MOBILE AL46013 DURHAM JEFF MOBILE AL46015 STEEN BILL MOBILE AL46017 FELDMAN EVAN MOBILE AL46018 SWIM STEVE UNKNOWN AL46019 BOGUE ROBERT PHOENIX JUNEマイカ・P・ホエニックス AZ46022 ケイン・シェリル 不明 AR46024 ウッド ウィリアム・マンシーIN46026 FERGUS SARAH MUNCIE IN46027 BUCK SARAH MUNCIE IN46029 TUTTLE BOB MUNCIE IN AWK が入力コンテンツを読み取ると、レコード全体が変数に割り当てられます。各フィールドはフィールド区切り文字で区切られ、変数 、 などに割り当てられます。行には基本的に無限の数のフィールドを含めることができ、各フィールドにはフィールド番号によってアクセスされます。したがって、コマンド awk {print ,,,,} names が生成する印刷出力は、 46012 DULANEY EVAN MOBILE AL46013 DURHAM JEFF MOBILE AL46015 STEEN BILL MOBILE AL46017 FELDMAN EVAN MOBILE AL46018 SWIM STEVE UNKNOWN AL46019 BOGUE ROBERT PHOENIX となります。 6021 6月 マイカ フェニックス AZ46022 ケインSHERYL UNKNOWN AR46024 WOOD WILLIAM MUNCIE IN46026 FERGUS SARAH MUNCIE IN46027 BUCK SARAH MUNCIE IN46029 TUTTLE BOB MUNCIE IN 注意すべき重要な点の 1 つは、AWK はスペースで区切られた 5 つのフィールドを解釈しますが、表示を印刷するときに、各フィールドの間にはスペースが 1 つしかないことです。各フィールドに一意の番号を割り当てる機能を使用すると、特定のフィールドのみを印刷するように選択できます。たとえば、各レコードの名前のみを印刷する場合は、印刷する 2 番目と 3 番目のフィールドを選択するだけです。 $ awk {print ,} emp_namesDULANEY EVANDURHAM JEFFSTEEN BILLFELDMAN EVANSWIM STEVEBOGUE ROBERTJUNE MICAHKANE SHERYLWOOD WILLIAMFERGUS SARAHBUCK SARAHTUTTLE BOB$ また、印刷フィールドで指定することもできます。レコード内での存在方法に関係なく、任意の順序で。したがって、名前フィールドを表示し、順序を逆にして、名、姓の順に表示します。 $ awk {print ,} emp_namesEVAN DULANEYJEFF DURHAMBILL STEENEVAN FELDMANSTEVE SWIMROBERT BOGUEMICAH JUNESHERYL KANEWILLIAM WOODSARAH FERGUSSARAH BUCKBOB TUTTLE$ パターンを使用するには、必ず次のパターンを含めます。 match を使用すると、すべてのレコードではなく特定のレコードのみを操作することを選択できます。パターン マッチングの最も単純な形式は、一致する項目をスラッシュ (/pattern/) で囲む検索です。たとえば、アラバマ州に住む従業員に対してのみ前述の操作を実行するには: $ awk /AL/ {print ,} emp_namesEVAN DULANEYJEFF DURHAMBILL STEENEVAN FELDMANSTEVE SWIM$ 印刷するフィールドを指定しない場合は、一致するエントリ全体が印刷されます。 : $ awk /AL/ emp_names46012 DULANEY EVAN MOBILE AL46013 DURHAM JEFF MOBILE AL46015 STEEN BILL MOBILE AL46017 FELDMAN EVAN MOBILE AL46018 SWIM STEVE UNKNOWN AL$ 同じデータ セットに対する複数のコマンドはセミコロン (;) で区切ることができます。たとえば、ある行に名前を出力し、別の行に都市と州を出力するには: $ awk /AL/ {print , ; print ,} emp_namesEVAN DULANEYMOBILE ALJEFF DURHAMMOBILE ALBILL STEENMOBILE ALEVAN FELDMANMOBILE ALSTEVE SWIMUNKNOWN AL$ セミコロンを使用しない場合 (print , ,,) はすべてを同じ行に表示します。一方、2 つの print ステートメントを別々に指定すると、まったく異なる結果が生成されます。 $ awk /AL/ {print ,} {print ,} emp_namesEVAN DULANEYMOBILE ALJEFF DURHAMMOBILE ALBILL STEENMOBILE ALEVAN FELDMANMOBILE ALSTEVE SWIMUNKNOWN ALPHOENIX AZPHOENIX AZUNKNOWN ARMUNCIE INMUNCIE INMUNCIE INMUNCIE IN$ は、リスト内に AL が見つかった場合、フィールド 3 と 2 のみを与えます。ただし、フィールド 4 と 5 は無条件であり、常に出力されます。最初の中括弧のセット内のコマンドのみが、その直前のコマンド (/AL/) に影響します。 結果は非常に読みにくいので、もう少しわかりやすくすることができます。まず、都市と州の間にスペースとカンマを挿入します。次に、表示される 2 行ごとに空行を置きます: $ awk /AL/ {print , ; print ", ""n"} emp_namesEVAN DULANEYMOBILE、ALJEFF DURHAMMOBILE、ALBILL STEENMOBILE、ALEVAN FELDMANMOBILE、ALSTEVE SWIMUNKNOWN、AL$ 5 番目のフィールドにカンマとスペース (引用符の間) を追加し、5 番目のフィールドの後に改行文字 (n) を出力します。 echo コマンドで使用できる次のような特殊文字はすべて、AWK print ステートメントでも使用できます。 n (改行) t (タブ) b (バックスペース) f (フィード) r (キャリッジ リターン)最初はタブで区切られた 5 つのフィールドをすべて取得し、タブを使用して印刷することもできます。次のようにプログラムできます。 $ awk {print "t""t""t""t"} emp_names46012 DULANEY EVAN MOBILE AL46013 DURHAM JEFF MOBILE AL46015 STEEN BILL MOBILE AL46017フェルドマン エヴァン モバイル AL46018 スイム スティーブ 不明 AL46019 ボーグ ロバート フェニックス AZ46021 ジューン マイカ フェニックス AZ46022 ケイン シェリル 不明 AR46024 ウッド ウィリアム マンシー IN460 26 ファーガス サラ マンシー IN46027 バック サラH MUNCIE IN46029 複数の項目を連続して設定することで TUTTLE BOB MUNCIE IN$ 標準でパイプで区切ります (| ) シンボルを使用すると、複数のパターン一致を一度に検索できます: $ awk /AL|IN/ emp_names46012 DULANEY EVAN MOBILE AL46013 DURHAM JEFF MOBILE AL46015 STEEN BILL MOBILE AL46017 FELDMAN EVAN MOBILE AL46018 SWIM STEVE UNKNOWN AL46024 WOOD WILLIAM MU NCIE IN46026 ファーガス・サラ・マンシー IN46027 バックSARAH MUNCIE IN46029 TUTTLE BOB MUNCIE IN$ これにより、アラバマ州とインディアナ州のすべての居住者に一致するレコードが検索されます。しかし、アリゾナに誰が住んでいるかを調べようとすると、問題が発生します。 $ awk /AR/ emp_names46019 BOGUE ROBERT PHOENIX AZ46021 JUNE MICAH PHOENIX AZ46022 KANE SHERYL UNKNOWN AZ46026 FERGUS SARAH MUNCIE IN46027 BUCK SARAH MUNCIE IN$Employees 4602 6 と 4 6027 住み込み禁止アリゾナ; ただし、名前には検索対象の文字列が含まれています。 grep、sed、その他ほとんどの Linux/Unix コマンドなどの AWK でパターン マッチングを行う場合、特に指定がない限り、レコード (行) 内の任意の場所で一致が見つかることに留意してください。この問題を解決するには、検索を特定のフィールドに結び付ける必要があります。これは、次の例に示すように、特定のフィールドの説明とともにチルダ (?) を使用することによって実現されます。 $ awk ? /AR/ emp_names46019 BOGUE ROBERT PHOENIX AZ46021 JUNE MICAH PHOENIX AZ46022 KANE SHERYL UNKNOWN AZ$ チルダ ( match ) は、感嘆符が前に付いたチルダ (!?) です。これらの文字は、指定されたフィールドに検索シーケンスが表示されない場合に、その検索シーケンスに一致するすべての行を検索するようにプログラムに指示します。 $ awk !? /AR/ names46012 DULANEY EVAN MOBILE AL46013 DURHAM JEFF MOBILE AL46015 STEEN BILL MOBILE AL46017 FELDMAN EVAN MOBILE AL46018 SWIM STEVE UNKNOWN AL46024 WOOD WILLIAM MUNCIE IN46026 FERGUS SARAH MUNCIE IN46027 BUCK SARAH MUNCIE IN46029 TUTTLE BOB MUNCIE IN$ この場合、5 番目のフィールドに AR のないすべての行が表示されます。これには、2 つの Sarah エントリが含まれます。どちらのエントリにも、 AR ですが、第 5 フィールドではなく第 3 フィールドにあります。 中括弧とフィールド区切り文字 中括弧文字は、AWK コマンドで重要な役割を果たします。括弧内に表示されるアクションは、何がいつ起こるかを示します。括弧のペアを 1 つだけ使用する場合: {print,} 括弧間のすべての操作が同時に実行されます。複数の括弧を使用する場合: {print }{print } は最初のコマンド セットを実行し、そのコマンドが 2 番目のコマンド セットを完了します。次の 2 つのリストの違いに注目してください。 $ awk {print ,} namesEVAN DULANEYJEFF DURHAMBILL STEENEVAN FELDMANSTEVE SWIMROBERT BOGUEMICAH JUNESHERYL KANEWILLIAM WOODSARAH FERGUSSARAH BUCKBOB TUTTLE$$ awk {print }{print } namesEVANDULANEYJEFFDURHAMBILLSTEENEVANFELDMANSTEVESWIMROBER T BOGUEMICAHJUNESHERYLKANEWILLIAMWOODSARAHFERGUSSARAHBUCKBOBTUTTLE$ 複数の括弧セットを使用して繰り返し検索を実行するには、最初のコマンドを実行します。グループ内のコマンドは完了するまで処理され、その後、2 番目のコマンド グループが処理されます。 3 番目のコマンド セットがある場合は、2 番目のコマンド セットが完了した後に実行され、以下同様に続きます。結果の印刷出力には 2 つの別々の印刷コマンドがあるため、最初のコマンドが最初に実行され、次に 2 番目のコマンドが実行され、各エントリが 1 行ではなく 2 行に表示されます。 2 つのフィールドを区別するフィールド区切り文字は、必ずしもスペースである必要はなく、認識される任意の文字を使用できます。デモンストレーションの目的で、emp_names ファイルがタブの代わりにコロンを使用してフィールドを区切っていると仮定します。モバイル:AL46018:スイム:スティーブ:不明:AL46019:ボーグ:ロバート:フェニックス:AZ46021:ジューン:マイカ:フェニックス:AZ46022:ケイン:シェリル:不明:AR46024:ウッド:ウィリアム:マンシー:IN4602