2012-03-12 15 views
1

以下は、書きたいスクリプトの一部です。スクリプトは私のiptablesログを開き、ログの各行に以下の例の詳細が入っています。Python - リストの問題(複数のリスト?)

 
#example of a single line 
#Mar 9 14:57:51 machine kernel: [23780.638839] IPTABLES Denied UDP: IN=p21p1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:00:00:00:00:00:00:00 SRC=10.100.1.4 DST=10.100.1.63 LEN=78 TOS=0x00 PREC=0x00 TTL=128 ID=10898 PROTO=UDP$ 

# Read file in a line at a time 
for line in iptables_log.readlines(): 
    #find time based on 4 letters, 2 spaces, up to 2 numbers, 1 space, then standard 10:10:10 time format 
    time = re.findall('(^\w{1,4}\s\s\d{1,2}\s\d\d:\d\d:\d\d)', line) 
    #mac lookup 
    mac = re.findall('MAC=(?:\w\w:\w\w:\w\w:\w\w\:\w\w:\w\w:\w\w:\w\w:\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)', line) 
    #source port 
    src = re.findall('SRC=(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})', line) 
    #destination port 
    dst = re.findall('DST=(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})', line) 
    #protocol 
    proto = re.findall('PROTO=(?:\w{3,4})', line) 
    #sourceport 
    sourceport = re.findall('SPT=(?:\w{1,5})', line) 
    #destport 
    destport = re.findall('DPT=(?:\w{1,5})', line) 
    print time, mac, src, dst, proto, sourceport, destport 
    print '======================================================' 

私は私がしたい項目だけを印刷するためのスクリプトを取得しようとしているが、スクリプトによって、その出力は、それがリストであるように思われ、このようになりますとき。私はそれが[']' 'なしで印刷したい。オンラインで見ると、すべての変数(時間、マック、srcなど)はリストそのものと同じように見えます。私はそれらをどのように組み合わせるか分からない。私は参加するための参照を見ましたが、この例を使用する方法はわかりません。誰か助けてもらえますか?

 
['Mar 9 14:57:51'] ['MAC=ff:ff:ff:ff:ff:ff:00:00:00:00:00:00:00:00'] ['SRC=10.100.1.4'] ['DST=10.100.1.63'] ['PROTO=UDP'] ['SPT=137'] ['DPT=137'] 
+2

なぜあなたは単一の正規表現でこれをしないのですか? – Kimvais

答えて

1

リストを展開するだけではどうですか?

あなただけ行うことができ
>>> time = [0] 
>>> [time] = time 
>>> time 
0 
+0

それはそれをしました...私はそこで何をしましたか?ありがとうございます –

+0

あなたはリストを解凍しました。 https://www.google.ca/search?q=list+unpacking+python –

+0

タプルのアンパックなどのアンパックの一覧表示: >>>タプル=(0,1) >>>(x、y)=タプル >>> x >>> y タプルのアンパックはもっと多く使われます(複数の結果を持つ関数/メソッドのタプルを返すことが多いためです)。 – QuidNovi

0

foo = re.findall(…)[0] 

一つだけの結果を期待するならば、私は

def findall(pattern, string, flags=0): 
    """Return a list of all non-overlapping matches in the string. 

    If one or more groups are present in the pattern, return a 
    list of groups; this will be a list of tuples if the pattern 
    has more than one group. 

    Empty matches are included in the result.""" 
    return _compile(pattern, flags).findall(string) 

リストを考え返すre.findall任意のre.findall

3

のために代わりにre.searchを使用してください。

>>> import re 
>>> st = '''Mar 9 14:57:51 machine kernel: [23780.638839] IPTABLES Denied UDP: IN=p21p1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:00:00:00:00:00:00:00 SRC=10.100.1.4 DST=10.100.1.63 LEN=78 TOS=0x00 PREC=0x00 TTL=128 ID=10898 PROTO=UDP$''' 
>>> x = re.search('(^\w{1,4}\s\s\d{1,2}\s\d\d:\d\d:\d\d)',st) 
>>> x.group(0) 
'Mar 9 14:57:51' 

(ソース= http://docs.python.org/library/re.html

+0

よろしくお願いします - ありがとうございます! –

+0

['re.search'](http://docs.python.org/library/re.html#re.search)は、文字列内の位置がパターンと一致しない場合には' None'を返します。だから、 'MatchObject'にアクセスする前に、あなたの結果が' None'でないかどうかチェックするべきです。 –

0

マッチのリストを返しre.findall。あなたのケースでは、値が1つしかないリストを取得しています。それが常に当てはまる場合、@ x539答えはリストの最初の項目を取得します。

0

私のような名前のグループと、行全体に対して単一の正規表現を使用することをお勧め:

>>> r = re.compile(r'^(?P<date>\w{1,4}\s\d{1,2}\s\d\d\:\d\d\:\d\d) (?P<hostname>\w+) kernel: (\[[0-9]+.[0-9]+\]) IN=(?P<ifacein>[a-z0-9]*) OUT=(?P<ifaceout>[a-z0-9]*) MAC=(?P<mac>[a-f0-9:]+) SRC=(?P<src>[\w.:]+) DST=(?P<dst>[\w:.]+) LEN=(?P<len>[0-9]+) TOS=0x(?P<tos>[0-9a-f]+) PREC=0x(?P<prec>[0-9a-f]+) TTL=(?P<ttl>[0-9]+) ID=(?P<id>[0-9]+) PROTO=(?P<proto>[A-Z]+) SPT=(?P<spt>[0-9]+) DPT=(?P<dpt>[0-9]+) LEN=(?P<len2>[0-9]+)') 
>>> d = r.match(line).groupdict() 
>>> d['dst'] 
'255.255.255.255' 
>>> d['proto'] 
'UDP' 
>>> d['dpt'] 
'17500' 

ます。また、簡単にあなたがしたいフィールドを持つ単一の文字列でそれをすべて取り戻すことができます。

>>> ' '.join([d[_] for _ in ("date", "mac", "src", "dst", "proto", "spt", "dpt")]) 
'Mar 12 13:06:10 ff:ff:ff:ff:ff:ff:00:18:8b:da:86:37:08:00 192.168.0.221 255.255.255.255 UDP 17500 17500' 
関連する問題