シェルを使ったデータ操作メモ

Webサービス運用で障害が発生した場合に、ログ漁りやDBからのデータ抜く出しをする機会があると思います。

その際にシェルを使ったログ漁りや補填のSQL発行などのメモを最近Qiita[キータ] - プログラマの技術情報共有サービスに投稿しているので、

ブログにもまとめてみます。

コマンドを覚える

コマンドを知らないと何もできないので、とりあえずコマンドを覚えましょう。

よく使うのはこのへん?コマンドの内容はググってもらえれば…。

では使ってみましょう

こんなログがあったとします

$ cat sample.log

127.0.0.1 - - [21/Feb/2013:00:06:20 +0900] "GET /feed/ HTTP/1.0" 304 - "-" "livedoor FeedFetcher/0.01 (http://reader.livedoor.com/; 1 subscriber)"

127.0.0.1 - - [21/Feb/2013:00:06:26 +0900] "GET / HTTP/1.0" 200 17702 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"

127.0.0.1 - - [21/Feb/2013:00:07:29 +0900] "GET / HTTP/1.0" 200 17702 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"

127.0.0.1 - - [21/Feb/2013:00:20:51 +0900] "POST /wp-cron.php?doing_wp_cron=1361373651.0959939956665039062500 HTTP/1.0" 200 - "-" "WordPress/3.5.1; http://slothlibrary.com"

127.0.0.1 - - [21/Feb/2013:00:20:51 +0900] "GET /12/ HTTP/1.0" 200 27053 "http://slothlibrary.com/12/" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; MRA 6.0 (build 5993); MRA 8.0 (build 5784); InfoPath.2)"

127.0.0.1 - - [21/Feb/2013:00:20:55 +0900] "POST /wp-comments-post.php HTTP/1.0" 302 - "http://slothlibrary.com/12/" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; MRA 6.0 (build 5993); MRA 8.0 (build 5784); InfoPath.2)"

127.0.0.1 - - [21/Feb/2013:00:20:57 +0900] "GET /12/ HTTP/1.0" 200 27122 "http://slothlibrary.com/12/#comment-218" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; MRA 6.0 (build 5993); MRA 8.0 (build 5784); InfoPath.2)"

127.0.0.1 - - [21/Feb/2013:00:33:19 +0900] "GET /robots.txt HTTP/1.0" 200 59 "-" "Mozilla/5.0 (compatible; MJ12bot/v1.4.3; http://www.majestic12.co.uk/bot.php?+)"

127.0.0.1 - - [21/Feb/2013:00:33:29 +0900] "GET /category/developer HTTP/1.0" 301 - "-" "Mozilla/5.0 (compatible; MJ12bot/v1.4.3; http://www.majestic12.co.uk/bot.php?+)"

127.0.0.1 - - [21/Feb/2013:00:33:36 +0900] "GET /category/developer/ HTTP/1.0" 200 14096 "-" "Mozilla/5.0 (compatible; MJ12bot/v1.4.3; http://www.majestic12.co.uk/bot.php?+)"

127.0.0.1 - - [21/Feb/2013:00:33:47 +0900] "GET /category/wordpress HTTP/1.0" 301 20 "-" "Mozilla/5.0 (compatible; MJ12bot/v1.4.3; http://www.majestic12.co.uk/bot.php?+)"

127.0.0.1 - - [21/Feb/2013:00:33:54 +0900] "GET /category/wordpress/ HTTP/1.0" 200 3415 "-" "Mozilla/5.0 (compatible; MJ12bot/v1.4.3; http://www.majestic12.co.uk/bot.php?+)"

127.0.0.1 - - [21/Feb/2013:00:44:44 +0900] "GET /feed/ HTTP/1.0" 200 2843 "-" "Feedfetcher-Google; (+http://www.google.com/feedfetcher.html; 5 subscribers; feed-id=11476985210332317360)"

127.0.0.1 - - [21/Feb/2013:00:45:41 +0900] "GET /wordpress_sakuravps_move/ HTTP/1.0" 200 7408 "http://slothlibrary.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/536.26.17 (KHTML, like Gecko) Version/6.0.2 Safari/536.26.17"

127.0.0.1 - - [21/Feb/2013:00:48:25 +0900] "GET / HTTP/1.0" 200 4677 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17"

127.0.0.1 - - [21/Feb/2013:00:48:28 +0900] "GET /wp-blog/index.php HTTP/1.0" 301 20 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17"

127.0.0.1 - - [21/Feb/2013:00:48:28 +0900] "GET /wp-blog/ HTTP/1.0" 404 2116 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17"

GETかPOSTのみを出力する

$ cat sample.log | awk '{print $6}'

"GET

"GET

"GET

"POST

"GET

"POST

"GET

"GET

"GET

"GET

"GET

POSTの数を抜き出す

$ grep POST sample.log | wc -l

2

GETの行を消して、POSTのみの行を表示させる

$ cat sample.log | sed -e '/GET/d'

127.0.0.1 - - [21/Feb/2013:00:20:51 +0900] "POST /wp-cron.php?doing_wp_cron=1361373651.0959939956665039062500 HTTP/1.0" 200 - "-" "WordPress/3.5.1; http://slothlibrary.com"

127.0.0.1 - - [21/Feb/2013:00:20:55 +0900] "POST /wp-comments-post.php HTTP/1.0" 302 - "http://slothlibrary.com/12/" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; MRA 6.0 (build 5993); MRA 8.0 (build 5784); InfoPath.2)"

とかとかこういう感じでアプリログを漁りまくって、いろいろデータを加工します。

Apache等Webサーバーが吐き出すログ等を抜き出すのが基本になりますが、その際にはシェルが欠かせません。

さて、次はMySQLから抜き出して、加工してみます。

MySQLのDBを抜き出したデータを加工してみる

こんな感じのテーブルがあったとします。

mysql> select id,user_id,data from user_data;

+----+---------+------+

| id | user_id | data |

+----+---------+------+

| 1 | 1 | 100 |

| 2 | 2 | 200 |

| 3 | 3 | 200 |

| 4 | 2 | 100 |

| 5 | 3 | 500 |

| 6 | 4 | 300 |

| 7 | 5 | 500 |

| 8 | 1 | 1000 |

| 9 | 4 | 300 |

| 10 | 2 | 500 |

| 11 | 2 | 200 |

+----+---------+------+

11 rows in set (0.00 sec)

で、合計値を抜き出して、1,000以上のdataを持っているユーザーのみを昇順に並び替えて抜き出します。

$ echo 'select user_id, sum(data) as data from user_data group by user_id having data >= 1000 order by data desc;' | mysql -uroot -ppassword -N test_db > sample.sql

$ cat sample.sql

1 1100

2 1000

別にデータを抜き出すだけなら、MySQLにログインして実施すればいいんですが、抜き出したデータを加工して、insert文をするとなるとこういう形で抜くのが良いです。

では抜き出したデータからinsert文を発行して実行しましょう。

(insertする内容は適当です)

$ awk '{printf("INSERT INTO user_data (user_id, data) VALUES (%d,%d);\n"),$1,$2;}' sample.sql > hoten.sql

$ cat hoten.sql

INSERT INTO user_data (user_id, data) VALUES (1,1100);

INSERT INTO user_data (user_id, data) VALUES (2,1000);

# あとはmysqlにくわせる

$ mysql -uroot -ppassword < hoten.sql

参考URL

独り言

まだまだ初心者の域は出てないけど、いろいろ楽しくなってきた