http ログ ファイルからホストを取得しようとしています。通常、私は次のようなことをします:
cat proxy.log | awk '{ print $16 }'
ただし、ログ ファイルは次のようにフォーマットされます。
2012-05-21 05:55:01 503 <client_ip> - - - OBSERVED "Entertainment" - 200 TCP_RESCAN_HIT GET text/xml;%20charset=UTF-8 http <server_ip> <server_host> 80 / ?feed=rss2 - "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; InfoPath.3; MS-RTC LM 8; Microsoft Outlook 14.0.6025; ms-office; MSOffice 14)" <proxy_ip> 13356 479 -
ご覧のとおり、一部のフィールドは引用符で囲まれており、動的な量の空白が含まれています。これは、$16 が常にホストを返すとは限らないことを意味します。これは、配列を返す shlex.split() を使用して Python で解決できます。
しかし、私が使用している一部のシステムには python がインストールされていません。これにより、bash スクリプト (標準の gnu ツールを使用) を作成してログエントリを分割し、たとえば $16 を一貫して処理できるようにする方法を知りたいと思います。
読者が同じ問題を抱えていて、Python を利用できる場合、これが私の Python ソリューションです。
#!/usr/bin/env python
import shlex, sys, string
EOF = ""
if len(sys.argv) == 2:
try:
field = int(sys.argv[1])
except ValueError:
print "error: <field_no> must be a positive integer"
sys.exit(1)
else:
print "usage: %s <field_no>" % sys.argv[0]
sys.exit(1)
def process(line):
line = string.strip(line)
line = shlex.split(line)
return line[int(sys.argv[1])]
line = sys.stdin.readline()
while not line == EOF:
sys.stdout.write(process(line)+"\n")
line = sys.stdin.readline()