FLINTERS Engineer's Blog

FLINTERSのエンジニアによる技術ブログ

文字列の一部を置換しながらファイルを複製する

こんにちは!@kakeyangです。


以前投稿したデモアカウント関連で、エントリしておきます。


Linux上で文字列の一部を置換しながらファイルを複製する方法です。


デモアカウントのデータ作成になぜこんなことが必要か?

うちの企画屋さんが、ご丁寧にリスティング広告のキーワード毎に異なる
データサンプルを作ってくれたからです(T_T)


僕はこれを、データ作成日数×3キャリア分横展開するために
100KW × 90日 × 3 = 27000
ものinsert文を発行するわけです。


ぎゃー!めんどくさい!
ということで以下の作戦で進めることにしました。


  1. 1ファイルに1日目のSQLだけを作成。100KW、3キャリア分。
  2. 2日目のSQLを1日目のファイルをコピーして作成。
  3. コピーされたファイルに記載されているSQLの、日付に相当する文字列のみ、
    2日目の日付に置換。
  4. 2〜3をループし、90日分作成。
  5. 90日分のファイルを一気にMySQLに流しこむ。
  6. 最後に全レコードの数値に乱数をかけ算し、それっぽく加工する。
以下に手順を記載しますが、「一部だけ異なる似た様なファイルを量産したい」場合に便利かと。

1日目のSQLを記載したファイルを作成する

こんな感じのSQLを記載したファイルを1個作ります。

$ touch 20110101.sql
$ vi ./20110101.sql


INSERT INTO REPORT_TBL (REPORT_DAY, KEYWORD_ID, ...) VALUES (20110101, 1, ...);
INSERT INTO REPORT_TBL (REPORT_DAY, KEYWORD_ID, ...) VALUES (20110101, 2, ...);
INSERT INTO REPORT_TBL (REPORT_DAY, KEYWORD_ID, ...) VALUES (20110101, 3, ...);

以下のスクリプトを流す

#!/bin/sh

start=`date -d '2011-01-01' '+%Y%m%d'`
end=`date -d '2011-01-30 1 days' '+%Y%m%d'`

date=$start
while [ $date -ne $end ]
do
	
	# 前日のファイルをコピー
	cpfile=`date -d "$date 1 days" '+%Y%m%d'`
	cp "$date.sql" "$cpfile.sql"
	
	# コピーして作成したファイルの日付を次の日に置換
	perl -p -i.bak -e "s/$date/$cpfile/g" $cpfile.sql

	# DBに流しこむ
	mysql -h xxx.xxx.xxx.xxx -uuserid -ppassword table <"$date.sql"

	date=`date -d "$date 1 days" '+%Y%m%d'`
done

exit 0

上の例は、20110102.sqlファイルを作成し、下記のように日付だけ置換する、
ということを繰り返しながら、2011/1/31分まで作成します。


INSERT INTO REPORT_TBL (REPORT_DAY, KEYWORD_ID, ...) VALUES (20110102, 1, ...);
INSERT INTO REPORT_TBL (REPORT_DAY, KEYWORD_ID, ...) VALUES (20110102, 2, ...);
INSERT INTO REPORT_TBL (REPORT_DAY, KEYWORD_ID, ...) VALUES (20110102, 3, ...);
どうも、ファイルを開かずに中身を書き換えることが出来ないので、

  • iオプションで.bak付きのファイルをコピーし、その内容を-eオプションで指定した

ルールに従って置換したファイルを、次のファイルとして作成しています。

最後に乱数を乗算してそれっぽく見せる

begin;
update
 REPORT_TBL
set
 data1 = round(data1 * (0.8 + RAND() * 0.4), 0),
 data2 = round(data2 * (0.8 + RAND() * 0.4), 0)
where
 client_id = xxx;
commit;

こんな感じで。これは作成したデータに±20%のゆらぎを持たせた例です。