1. yamap_55

    タイポを修正

    yamap_55
Changes in body
Source | HTML | Preview
@@ -1,86 +1,86 @@
# Q. awk '{print $9}'とかでUser-Agent丸ごと取り出したい
とか思ったことない? Apacheのログ解析で。でもできないじゃない。例えば
```text:combined形式ログ
192.168.0.1 - - [17/Apr/2014:11:22:33 +0900] "GET /index.html HTTP/1.1" 200 43206 "https://www.google.co.jp/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36"
```
なんかのログで`"mozilla/5.0 (Windows NT 6.1 …… Safari/537.36"`の部分が欲しいなーと思って、AWKで取ろうとしても
```sh:こーなってしまう
$ awk '{print $12}' httpd-access.log
"Mozilla/5.0
$
```
なーんてふうに、最初のスペースまでで切れてしまって全然使い物にならない。さて、何とかならないものか。
# A. 6個のsedコマンドにパイプで通せばできるよ
でも、そこは我らがUNIX。シェルスクリプトとパイプと標準コマンドさえあればお手のもの。sedコマンド6個通すだけでできるようになるのさ。
次のシェルスクリプトを書いてこいつに流し込むだけ。
**(2014/05/05) おい、動かねーじゃねーか!という指摘を受けて修正しました。m(_ _;)m**
```sh:apalognorm.sh(Apachログを整形するシェルスクリプト)
#! /bin/sh
# ----- ちょいと下ごしらえ -----
RS=$(printf '\036') # 元々の改行位置にマークするための記号定義
LF=$(printf '\\\n_');LF=${LF%_} # sedで改行コードを挿れるための定義
# ----- 本番 -----
sed 's/^\(.*\)$/\1'"$RS"'/' |
sed 's/"\([^"]*\)"/'"$LF"'"\1"'"$LF"'/g' |
sed 's/\[\([^]]*\)\]/'"$LF"'[\1]'"$LF"'/g' |
sed '/^["[]/s/[[:blank:]]/_/g' | # ここに空白の代替文字
sed 'N;$s/\n//g' |
sed 's/'"$RS"'/'"$LF"'/g'
```
試しに実行してみると、
```sh:ほらこのとおり
$ cat httpd-access.log | apalognorm.sh
192.168.0.1 - - [17/Apr/2014:11:22:33_+0900] "GET_/index.html_HTTP/1.1" 200 43206 "https://www.google.co.jp/" "Mozilla/5.0_(Windows_NT_6.1;_WOW64)_AppleWebKit/537.36_(KHTML,_like_Gecko)_Chrome/34.0.1847.116_Safari/537.36"
$
```
日時列(4列目)、HTTPリクエストパラメーター列(5列目)、User-Agent列(9列目)に含まれているスペースが全て`_`に置換されている。もちろん、列を区切っているスペースはそのままで。
もし、`_`が気に食わないのであれば`*`でも`+`でも、好きな文字列(2文字以上でもいい)を4番目のsedの後半部分に書けばいいだけ。
# 6つのsedは何をやってるのか?
## sed 1号
(加工の都合により、途中で一時的に改行を挿むので)元の改行を別の文字(0x1e)で退避させておく。
## sed 2号
ダブルクォーテーションで囲まれている区間`"~"`があったら、その前後に改行を挿み、その区間を単独の行にする。
## sed 3号
ブラケットで囲まれいる区間`[~]`も同様に、前後に改行を挿んで、この区間を単独の行にする。
## sed 4号
ダブルクォーテーション、またはブラケットで始まる行は、先程行を独立させた区間なので、これらの行にある空白をそうでない文字列に置換する。
## sed 5号
改行を全部取り除く。(これはべつにsedでやる必要ないのだけど)
## sed 6号
退避させていた元々の改行を復活させる。(これもべつにsedでやる必要ないのだけど)
# コマンド化したものをGitHubに置いておいたよ
-例によってちゃんとコマンド化したものを[Gistに上げておいた](https://gist.github.com/richmikan/7254345)。ログ解析で困っているなら使ってみてね。スペースの代替文字が`_`では気に入らない人向けに、オプションで指定できるよにしてある本格派だ。
+例によってちゃんとコマンド化したものを[Gistに上げておいた](https://gist.github.com/richmikan/7254345)。ログ解析で困っているなら使ってみてね。スペースの代替文字が`_`では気に入らない人向けに、オプションで指定できるよにしてある本格派だ。
Apacheサーバー管理者は、これで少し幸せになれるかも。
尚、Gistに上げたものは、5号と6号のsedはtrに置き換えているので悪しからず。まぁ、全部sedでやるというのはネタだからねぇ。