こんにちは。よっしーです(^^)
今日は、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形式のテストデータを生成するスクリプトです。以下に、コードの各部分の解説を示します。
BEGIN
ブロック:
OFS=","
: フィールド(列)の区切り文字をコンマに設定します。rowMax=10
: 生成するデータの行数を10に設定します。
printHeader
関数:
- CSVファイルのヘッダー行を出力します。列の名前は「id」「uuid」「value」「created_at」「updated_at」です。
generateUUID
関数:
uuidgen
コマンドを使用してランダムなUUIDを生成します。getline
を使って標準出力から読み取り、close
でプロセスを終了します。
getCurrentDateTime
関数:
date
コマンドを使用して現在の日時(”%Y-%m-%d %H:%M:%S”フォーマット)を生成します。getline
とclose
を使用して標準出力から読み取り、プロセスを終了します。
getUpdatedDateTime
関数:
- 引数として受け取った日数を加算して、将来の日時を生成します。
date -v
オプションは、BSD系のdate
コマンドで、指定した日数だけ日時を進めることができます。
printData
関数:
- 引数として渡されたデータをもとに、フォーマットされた文字列を作成し、その行を出力します。
printf
を使用して、各列のデータとフィールド区切り文字 (OFS
)、行区切り文字 (ORS
) を指定します。
最終的に、BEGIN
ブロック内でprintHeader
を呼び出し、その後ループで各行のデータを生成し出力しています。生成されたデータは、id
、uuid
、ランダムなvalue
、created_at
、およびupdated_at
の列を持つCSV形式のファイルになります。
getlineとcloseコマンド
awk
のgetline
コマンドは、外部コマンドやファイルから入力を読み込むための機能です。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のテストデータを作成にする方法についてご紹介しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント