テキスト ファイルの並べ替えに役立つ Awk コマンドラインまたはスクリプト (推奨)

テキスト ファイルの並べ替えに役立つ Awk コマンドラインまたはスクリプト (推奨)

Awk は、ソートを含む他の一般的なユーティリティによって実行できるいくつかのタスクを実行できる強力なツールです。

Awk は、予測可能なパターンを含むテキストをスキャンして処理するための、広く使用されている Unix コマンドです。しかし、機能的な能力を備えているため、プログラミング言語と呼ぶこともできます。

紛らわしいことに、awk は複数存在します。 (または、1 つしかないと思う場合、他はクローンです。) awk (Aho、Weinberger、および Kernighan によって書かれた元のプログラム) があり、次に nawk、mawk、および gawk の GNU バージョンがあります。 GNU バージョンの awk は、いくつかの独自の機能を備えたユーティリティの移植性の高いフリー ソフトウェア バージョンであるため、この記事では GNU awk について説明します。

正式名称は gawk ですが、GNU+Linux システムでは awk という別名が付けられ、コマンドのデフォルト バージョンとして使用されます。 GNU awk が付属していない他のシステムでは、まずそれをインストールし、awk ではなく gawk と呼ぶ必要があります。この記事では、awk と gawk という用語を同じ意味で使用します。

awk はコマンド言語であると同時にプログラミング言語でもあり、sort、cut、uniq などの一般的なユーティリティに使用されるタスクを実行するための強力なツールです。幸いなことに、オープンソースには冗長性の余地が十分にあるので、awk を使用するかどうかという質問に直面した場合、答えはおそらく「何でもいい」となるでしょう。

awk の柔軟性の優れた点は、タスクを実行するために awk を使用することを決定した場合、次に何が起こっても awk を使い続けることができることです。これには、データが配信された順序ではなく、データを並べ替えるという永続的な必要性が含まれます。

サンプルデータセット

awk のソート方法を調べる前に、作業に使用するサンプル データ セットを生成します。エッジケースや予期しない複雑さに悩まされないように、シンプルさを保ちます。この記事で使用したサンプル セットは次のとおりです。

アプテノディテス;フォルステリ;ミラー、JF;1778;皇帝
Pygoscelis;パプア;ワグラー;1832;ジェンツー
ユーディプトゥラ;マイナー;ボナパルト;1867;リトルブルー
Spheniscus;demersus;Brisson;1760;アフリカ
メガディプテス;対蹠類;ミルン・エドワーズ;1880;キバタヒバリ
Eudyptes;chrysocome;Viellot;1816;ミナミイワトビ
トルバルディス;Linux;ユーイング、L;1996;タックス

これは小さなデータセットですが、さまざまなデータ タイプを提供します。

  • 属名と種名は関連しているが別々である
  • 姓、イニシャルの場合は先頭にコンマを付ける
  • 日付を表す整数
  • 任意の用語
  • すべてのフィールドはセミコロンで区切られます。

教育的背景に応じて、これを 2 次元配列またはテーブル、あるいは単に行で区切られたデータのコレクションと考えることができます。どのように見るかはあなたの問題です。awk はテキストのみを認識します。どのように解析するかを awk に指示するのはあなた次第です。

並べ替えたいだけ

テキスト データセットを特定の定義可能なフィールド (スプレッドシートの「セル」など) でのみ並べ替える場合は、sort コマンドを使用できます。

フィールドとレコード

入力の形式に関係なく、重要なデータ部分に焦点を当てることができるように、入力内のパターンを見つける必要があります。この例では、データは行とフィールドという 2 つの要素によって区切られています。各行は、スプレッドシートやデータベース ダンプに表示されるのと同じように、新しいレコードを表します。各行には、セミコロン (;) で区切られたさまざまなフィールド (スプレッドシートのセルのようなものと考えてください) があります。

Awk は一度に 1 つのレコードのみを処理するため、awk に送信される命令を作成するときは、レコードの 1 行のみに集中できます。 1 行のデータで何をしたいかを書き留め、次の行でそれをテストし (頭の中で、または awk を使用して)、その後、他のテストをいくつか実行します。最後に、awk スクリプトが処理するデータについていくつかの仮定を立てて、必要な構造でデータを提供できるようにする必要があります。

この例では、各フィールドがセミコロンで区切られていることが簡単にわかります。簡単にするために、各行の最初のフィールドでリストを並べ替えるとします。

ソートを実行する前に、awk が各行の最初のフィールドのみにフォーカスするようにする必要があります。これが最初のステップです。ターミナルでの awk コマンドの構文は、awk、その後に関連するオプション、最後に処理するデータ ファイルです。

$ awk --field-separator=";" '{print $1;}' ペンギンリスト
アプテノダイテス
ピゴセリス
ユーディプトゥラ
スフェニスカス
メガディプテス
ユーディプテス
トルバルディス

フィールド区切り文字は Bash シェルにとって特別な意味を持つ文字であるため、セミコロンを引用符で囲むか、その前にバックスラッシュを付ける必要があります。このコマンドは、特定の分野に特化できることを証明するためにのみ使用されます。別のフィールド番号を使用して同じコマンドを実行し、データの別の「列」の内容を確認することもできます。

$ awk --field-separator=";" '{print $3;}' ペンギンリスト
ミラー、J.F.
ワグラー
ボナパルト
ブリッソン
ミルン・エドワーズ
ヴィエロ
ユーイング、L

まだソートは行っていませんが、これは良い基礎です。

スクリプト

awk は単なるコマンドではなく、インデックス、配列、関数を備えたプログラミング言語です。これは、並べ替えるフィールドのリストを取得し、そのリストをメモリに保存し、処理を実行して、結果のデータを印刷できることを意味するため重要です。このような複雑な一連の操作の場合は、テキスト ファイルで実行する方が簡単なので、sort.awk という新しいファイルを作成し、次のテキストを入力します。

#!/bin/gawk -f
始める {
    FS=";";
}

これにより、実行される行を含む awk スクリプトにファイルが構築されます。

BEGIN ステートメントは、1 回だけ実行する必要があるタスク用に awk によって提供される特別なセットアップ関数です。組み込み変数 FS を定義します。これはフィールド区切り文字を表し、awk コマンドの --field-separator で設定する値と同じです。これは 1 回だけ実行する必要があるため、BEGIN ステートメントに含まれています。

awk の配列

$ 記号とフィールド番号を使用して特定のフィールドの値を収集する方法はすでにご存知ですが、この場合は、ターミナルに出力するのではなく、配列に保存します。これは awk 配列を使用して行われます。 awk 配列に関して重要なことは、キーと値が含まれていることです。 この記事の内容を想像してみてください。次のようになります: author:"seth",title:"How to sort with awk",length:1200。著者、タイトル、長さなどの要素がキーであり、それに続くコンテンツが値です。

ソートのコンテキストでこれを行う利点は、任意のフィールドをキーとして割り当て、任意のレコードを値として割り当て、組み込みの awk 関数 asorti() (インデックスによるソート) を使用してキーでソートできることです。ここで、2 番目のフィールドのみで並べ替えたいと仮定してみましょう。

特殊キーワード BEGIN または END で囲まれていない awk ステートメントは、各レコードに対して実行されるループです。これは、データをスキャンしてパターンを検出し、それに応じて処理するスクリプトの部分です。 awk がレコードに注目するたびに、{} 内のステートメントが実行されます (BEGIN または END が先行しない限り)。

配列にキーと値を追加するには、配列を含む変数を作成し (このサンプル スクリプトでは ARRAY と呼びます。あまり独創的ではありませんがわかりやすいです)、角括弧で囲んだキーと等号 (=) で囲んだ値を割り当てます。

{ # 各フィールドを配列にダンプする
  配列[$2] = $R;
}

このステートメントでは、2 番目のフィールド ($2) の内容がキーとして使用され、現在のレコード ($R) が値として使用されます。

asorti() 関数

配列に加えて、awk には、一般的なタスクの迅速かつ簡単なソリューションとして使用できるいくつかの基本関数があります。 GNU awk で導入された関数の 1 つである asorti() は、配列をキー (インデックス) または値でソートする機能を提供します。

配列を並べ替えることができるのは、配列にデータが入力された後のみです。つまり、この操作は新しいレコードごとにトリガーされるのではなく、スクリプトの最後でのみトリガーされます。この目的のために、awk は特別な END キーワードを提供します。 BEGIN とは異なり、END ステートメントはすべてのレコードがスキャンされた後に 1 回だけ実行されます。

スクリプトに以下を追加します:

終わり {
  配列をソートする
  # 長さを取得
  j = 長さ(SARRAY);
  
  (i = 1; i <= j; i++) の場合 {
    printf("%s %s\n", SARRAY[i],ARRAY[SARRAY[i]])
  }
}

asorti() 関数は ARRAY の内容を受け取り、インデックスでソートし、その結果を SARRAY (この記事のために私が作った任意の名前で、「sorted ARRAY」の略) という新しい配列に格納します。

次に、変数 j (別の任意の名前) に、SARRAY 内の項目数をカウントする length() 関数の結果が割り当てられます。

最後に、 for ループを使用して、printf() 関数を使用して SARRAY 内の各項目を反復処理し、各キーを出力してから、ARRAY 内のそのキーに対応する値を出力します。

スクリプトを実行する

awk スクリプトを実行するには、実行可能にします。

$ chmod +x sorter.awk

次に、penguin.list のサンプル データに対して実行します。

$ ./sorter.awk ペンギンリスト
対蹠類メガディプテス;対蹠類;ミルン・エドワーズ;1880;キバタヒバリ
クリソコム Eudyptes;クリソコム;Viellot;1816;サザンイワトビ
demersus Spheniscus;demersus;Brisson;1760;アフリカ
forsteri Aptenodytes;forsteri;Miller,JF;1778;Emperor
linux Torvaldis;linux;Ewing,L;1996;Tux
マイナー Eudyptula;マイナー;ボナパルト;1867;リトルブルー
パプア Pygoscelis;パプア;ワグラー;1832;ジェンツー

ご覧のとおり、データは 2 番目のフィールドでソートされています。

これは少し制限があります。このスクリプトを任意のデータセットで使用して意味のある結果を得るためには、実行時にソートキーとして使用するフィールドを柔軟に選択できると便利です。

コマンドオプションを追加する

スクリプト内でリテラル値 var を使用して、awk スクリプトにコマンド変数を追加できます。配列を作成するときに反復句が var を使用するようにスクリプトを変更します。

{ # 各フィールドを配列にダンプする
  配列[$var] = $R;
}

スクリプトを実行するときに -v var オプションを使用して、3 番目のフィールドでソートされるようにスクリプトを実行してみてください。

$ ./sorter.awk -v var=3 ペンギンリスト
ボナパルト エウディプトゥラ;マイナー;ボナパルト;1867;リトルブルー
Brisson Spheniscus;demersus;Brisson;1760;アフリカ
Ewing、L Torvaldis;linux;Ewing、L;1996;Tux
ミラー、JF アプテノディテス;フォルステリ;ミラー、JF;1778;皇帝
ミルン-エドワーズ メガディプテス;対蹠類;ミルン-エドワーズ;1880;キバタヒバリ
Viellot Eudyptes;chrysocome;Viellot;1816;ミナミイワトビ
Wagler Pygoscelis;パプア;Wagler;1832;ジェンツー

リビジョン

この記事では、純粋な GNU awk でデータをソートする方法を説明します。スクリプトを自分にとって便利なものに改善するには、gawk のマニュアル ページで awk 関数を時間をかけて学習し、スクリプトをカスタマイズしてより良い出力を得ることができます。

これまでの完全なスクリプトは次のとおりです。

#!/usr/bin/awk -f
# GPLv3がここに登場
# 使用法: ./sorter.awk -v var=NUM FILE
開始 { FS=";"; }
{ # 各フィールドを配列にダンプする
  配列[$var] = $R;
}
終わり {
  配列をソートする
  # 長さを取得
  j = 長さ(SARRAY);
  
  (i = 1; i <= j; i++) の場合 {
    printf("%s %s\n", SARRAY[i],ARRAY[SARRAY[i]])
  }
}

要約する

上記は、テキスト ファイルの並べ替えに役立つ Awk コマンドラインまたはスクリプトです。お役に立てば幸いです。ご質問がある場合は、メッセージを残してください。すぐに返信いたします。また、123WORDPRESS.COM ウェブサイトをサポートしてくださっている皆様にも感謝申し上げます。
この記事が役に立ったと思われた方は、ぜひ転載していただき、出典を明記してください。ありがとうございます!

以下もご興味があるかもしれません:
  • awk スクリプトを Python に移植する方法
  • シェルスクリプトの正規表現、grep、sed、awk
  • シェルスクリプトでのawkコマンドの使用
  • Linuxシェルスクリプトでは、配列がawkに渡されて処理されます。
  • Linux awk 時間計算スクリプトと awk コマンドの詳細な説明

<<:  MySQL に大量のデータを挿入する 4 つの方法の例

>>:  WeChatアプレットはシンプルな手書き署名コンポーネントを実装します

推薦する

Mysql 主キー UUID と自動増分主キーの違いと利点と欠点

導入私はしばらくの間、postgresql データベースを使用していました。クラウドに移行した後、自...

純粋な CSS3 で実装された三目並べゲーム

操作効果: html <div class="三目並べ"> <...

Vueデータ割り当て問題の解決

私が長い間遭遇してきた問題を要約してみましょう。プロジェクトでは、フロントエンドをレンダリングするた...

Mysql | ワイルドカード(%、_ など)を使用したファジークエリの詳細な説明

ワイルドカードのカテゴリ: %パーセント ワイルドカード: 任意の文字が任意の回数出現できることを示...

CSS3 で高さと幅を不定にして垂直と水平に中央揃えするいくつかの方法

1. フレックスレイアウト 。父親 { ディスプレイ: フレックス; コンテンツの中央揃え: 中央;...

CSS で写真のスタッキング効果を実装するサンプルコード

成果を達成するステップ1. 初期index.html最初の写真、一番上の写真を作成します。写真の i...

Linux で大きなファイルの内容を消去または削除する 5 つの方法

Linux ターミナルでファイルを操作しているときに、Linux コマンドライン エディターでファイ...

Linux で複数のファイルの名前を一括で変更する方法

Linux では、通常、ファイルの名前を変更するために mv コマンドを使用します。これは、単一のフ...

overflow:hidden の役割の詳細な説明 (オーバーフローの非表示、フロートのクリア、マージンの崩壊の解決)

1. オーバーフロー:非表示 オーバーフロー非表示要素に overflow:hidden が設定さ...

デザインリファレンス 美しく独創的なブログデザイン

以下にリストされているすべてのブログはオリジナルであり、独自にデザインされています。これらは、他者が...

Nginxはドメイン名のアクセス方法を定義しています

最近Nginxを構築しているのですが、ドメイン名でアクセスできません。 nginx 構成ファイル n...

Angular構造ディレクティブモジュールとスタイルの詳細な説明

目次1. 構造指示モジュールforRoot()を書く3. スタイルの定義ドラッグ時の順序を調整するに...

Web ページのデザインを学ぶときに習得すべきコードは何ですか?

この記事では、Web ページ制作を学ぶ過程で習得すべきテクニックの一部を詳しく紹介します。これらの内...

Vue はデータの変更をどのように追跡しますか?

目次背景例誤解 - コールスタックを表示するためにウォッチでブレークポイントを設定する正しいアプロー...

Reactの仮想DOMとdiffアルゴリズムの詳細な説明

仮想DOMの役割まず、仮想 DOM の出現によってどのような問題が解決されるのかを知る必要があります...