Python - Список проблем (несколько списков?)
Вопрос
Ниже приведена часть скрипта, я пытаюсь написать.Сценарий открывает My Log iptables, каждая строка в журнале содержит детали в примере ниже.
#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 '======================================================'.
Я пытаюсь заставить скрипт напечатать только предметы, которые я хочу, но когда его вывод скрипта выглядит так, кажется, что, кажется, является списком.Я хочу, чтобы это печатать без [] ''.Глядя в Интернете, кажется, что каждая переменная (время, Mac, 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'].
Решение
Почему бы не просто распаковать ваши списки?
>>> time = [0]
>>> [time] = time
>>> time
0
. Другие советы
re.findall возвращает список
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.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'
.
(Source= http://docs.cython.org/library/re.html)
Вы могли бы просто сделать:
foo = re.findall(…)[0]
.
Если вы ожидаете только один результат, для любого Re.findall
re.findall возвращает список совпадений.В вашем случае вы получаете списки только с одним значением.Если это всегда так, то @ X539 ответ получит первый элемент в списке.
Я предлагаю использовать одно Regexp для всей линии, с названными группами, такими как:
>>> 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'
.