AWK入門:CSV形式のテストデータを作成する

スポンサーリンク
AWK入門:CSV形式のテストデータを作成する ノウハウ
AWK入門:CSV形式のテストデータを作成する
この記事は約8分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

今日は、AWKでCSVのテストデータを作成にする方法についてご紹介します。

スポンサーリンク

背景

AWKでテストデータを作成する機会があったので、そのときの内容を備忘としてのこしました。

作成するテストデータ例

下記のテストデータを作成します。

id,uuid,value,created_at,updated_at
連番,UUID,乱数,作成日時,作成日時にid日を足した日時

作成するコード

下記の内容で、gen_csv.awk を作成します。

BEGIN {
    OFS=","
    rowMax=10

    # ヘッダー
    printHeader()

    # CSVデータ
    for(i=1; i<=rowMax; i++) {
        uuid = generateUUID()
        createdAt = getCurrentDateTime()
        updatedAt = getUpdatedDateTime(i)
        printData(i, uuid, rand() * 1000, createdAt, updatedAt)
    }
}

function printHeader() {
    print "id", "uuid", "value", "created_at", "updated_at"
}

function generateUUID() {
    "uuidgen" | getline uuid
    close("uuidgen")
    return uuid
}

function getCurrentDateTime() {
    "date +'%Y-%m-%d %H:%M:%S'" | getline createdAt
    close("date")
    return createdAt
}

function getUpdatedDateTime(days) {
    getUpdateAtCmd = "date -v+" days "d +'%Y-%m-%d %H:%M:%S'"
    getUpdateAtCmd | getline updatedAt
    close("date")
    return updatedAt
}

function printData(id, uuid, value, createdAt, updatedAt) {
    fmt = "%d%s"     # id
    fmt = fmt "%s%s" # uuid
    fmt = fmt "%d%s" # value
    fmt = fmt "%s%s" # created_at
    fmt = fmt "%s%s" # updated_at
    printf(fmt \
        , i \
        , OFS \
        , uuid \
        , OFS \
        , value \
        , OFS \
        , createdAt \
        , OFS \
        , updatedAt \
        , ORS \
    );
}

実行方法

下記のコマンドを実行します。

awk -f gen_csv.awk

下記のような出力になっていれば成功です。

id,uuid,value,created_at,updated_at
1,4B969091-F1D3-491B-9D2F-3815146A7CC4,840,2023-11-26 14:58:06,2023-11-27 14:58:06
2,5087E7DF-8826-47CB-8078-0482C1804DCC,394,2023-11-26 14:58:06,2023-11-28 14:58:06
3,6842ED08-3868-4366-8CDE-4839356BDD03,783,2023-11-26 14:58:06,2023-11-29 14:58:07
4,A102D5BC-A817-4FD7-801B-64884B3A4E94,798,2023-11-26 14:58:06,2023-11-30 14:58:07
5,DFAF1E65-3EAE-49AB-B7CA-4233199A5225,911,2023-11-26 14:58:06,2023-12-01 14:58:07
6,A2A319E0-EE21-444A-9885-0E9342CEFD2C,197,2023-11-26 14:58:06,2023-12-02 14:58:07
7,99DF1B98-D80F-4C4C-BF41-5AECFA6A0283,335,2023-11-26 14:58:06,2023-12-03 14:58:07
8,E90116A9-9438-48C8-8A59-DF40E916AFE6,768,2023-11-26 14:58:06,2023-12-04 14:58:07
9,9A8B582B-73AF-47D7-B75E-57DF932620B2,277,2023-11-26 14:58:06,2023-12-05 14:58:07
10,84BAD2C9-576D-487D-ACF1-D94AD8B56FAE,553,2023-11-26 14:58:06,2023-12-06 14:58:07

解説

gen_csv.awk

このコードは、awkを使用してCSV形式のテストデータを生成するスクリプトです。以下に、コードの各部分の解説を示します。

  1. BEGINブロック:
  • OFS=",": フィールド(列)の区切り文字をコンマに設定します。
  • rowMax=10: 生成するデータの行数を10に設定します。
  1. printHeader関数:
  • CSVファイルのヘッダー行を出力します。列の名前は「id」「uuid」「value」「created_at」「updated_at」です。
  1. generateUUID関数:
  • uuidgenコマンドを使用してランダムなUUIDを生成します。getlineを使って標準出力から読み取り、closeでプロセスを終了します。
  1. getCurrentDateTime関数:
  • dateコマンドを使用して現在の日時(”%Y-%m-%d %H:%M:%S”フォーマット)を生成します。getlinecloseを使用して標準出力から読み取り、プロセスを終了します。
  1. getUpdatedDateTime関数:
  • 引数として受け取った日数を加算して、将来の日時を生成します。date -vオプションは、BSD系のdateコマンドで、指定した日数だけ日時を進めることができます。
  1. printData関数:
  • 引数として渡されたデータをもとに、フォーマットされた文字列を作成し、その行を出力します。printfを使用して、各列のデータとフィールド区切り文字 (OFS)、行区切り文字 (ORS) を指定します。

最終的に、BEGINブロック内でprintHeaderを呼び出し、その後ループで各行のデータを生成し出力しています。生成されたデータは、iduuid、ランダムなvaluecreated_at、およびupdated_atの列を持つCSV形式のファイルになります。

getlineとcloseコマンド

awkgetlineコマンドは、外部コマンドやファイルから入力を読み込むための機能です。getlineは標準入力から読み込むだけでなく、コマンドやファイルからも読み込むことができます。また、closeコマンドはgetlineで開いたファイルやコマンドのプロセスを閉じるために使用します。

具体的な説明を以下に示します。

getlineコマンド

getlineは、標準入力からデータを読み込む際に使われますが、通常は外部コマンドやファイルからの読み込みに使用されます。

例1: ファイルからの読み込み

# ファイル "example.txt" の内容を読み込んで処理する例
{
    while ((getline line < "example.txt") > 0) {
        # ここで行を処理する
        print line
    }
    close("example.txt")  # ファイルを閉じる
}

例2: コマンドからの読み込み

# 外部コマンド "ls" の出力を読み込んで処理する例
{
    while ((getline line < "ls") > 0) {
        # ここで行を処理する
        print line
    }
    close("ls")  # コマンドのプロセスを閉じる
}

closeコマンド

closeコマンドは、getlineで開かれたファイルやコマンドのプロセスを閉じるために使用します。これにより、ファイルディスクリプタやプロセスが解放され、不要なリソースリークを防ぎます。

{
    # ファイルからの読み込み
    while ((getline line < "example.txt") > 0) {
        # ここで行を処理する
        print line
    }
    close("example.txt")  # ファイルを閉じる

    # 別のファイルからの読み込み
    while ((getline another_line < "another.txt") > 0) {
        # ここで別の行を処理する
        print another_line
    }
    close("another.txt")  # 別のファイルを閉じる
}

closeを使うことで、新しいファイルやコマンドを開く前に前のファイルやコマンドを閉じることが重要です。これにより、不要なリソースの使用を避けることができます。

おわりに

今日は、AWKでCSVのテストデータを作成にする方法についてご紹介しました。

よっしー
よっしー

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました