line.split () индекс назначения списка вне диапазона - PullRequest
0 голосов
/ 24 мая 2018

В настоящее время я сталкиваюсь с этой ошибкой для следующего кода: chain['xxx']=line.split()[10] IndexError: list index out of range

import xlsxwriter

word='Chain'

def create_chain(chain_segment):
    chains=[]
    chain_lines = [line for line in chain_segment.split('\n') if line]
    for line in chain_lines:
        chain={}
        if word in line:
            chain['type'] = line.split()[1]
        elif line[0].isdigit():
            chain['num']=line[0]
            chain['pkts']=line.split()[1]
            chain['bytes']=line.split()[2]
            chain['target']=line.split()[3]
            chain['prot']=line.split()[4]
            chain['opt']=line.split()[5]
            chain['in']=line.split()[6]
            chain['out']=line.split()[7]
            chain['source']=line.split()[8]
            chain['destination']=line.split()[9]
            chain['xxx']=line.split()[10]
        chains.append(chain)
        chains=filter(None, chains)
    chains=list(chains)
    chained = [merge_dicts(chains[0], i) for i in chains[1:]]
    return chained

def merge_dicts(x,y):
   z=x.copy()
   z.update(y)
   return z

with open('/media/sf_vboxshared/iptables-list.log') as f:
    log_content = f.read()

host_sections = [host for host in log_content.split('---') if host]
hosts = {}

for host in host_sections:
    hostname, chains_segment = host.split('\n', 1)
    hostname = hostname.strip()
    chains=[]
    for segment in chains_segment.split('\n\n'):
            chains.extend(create_chain(segment))
    hosts[hostname] = chains

workbook=xlsxwriter.Workbook('/media/sf_vboxshared/iptables-1st.xlsx')
worksheet1=workbook.add_worksheet('Sheet1')

worksheet1.write(0,0,'hostname')
worksheet1.write(0,1,'chain')
worksheet1.write(0,2,'num')
worksheet1.write(0,3,'pkts')
worksheet1.write(0,4,'bytes')
worksheet1.write(0,5,'target')
worksheet1.write(0,6,'prot')
worksheet1.write(0,7,'opt')
worksheet1.write(0,8,'in')
worksheet1.write(0,9,'out')
worksheet1.write(0,10,'source')
worksheet1.write(0,11,'destination')
row = 1

for host, chains in hosts.items():
    for chain in chains:
        worksheet1.write(row, 1, chain.get('type'))
        worksheet1.write(row, 0, host)
        worksheet1.write(row, 2, chain.get('num'))
        worksheet1.write(row, 3, chain.get('pkts'))
        worksheet1.write(row, 4, chain.get('bytes'))
        worksheet1.write(row, 5, chain.get('target'))
        worksheet1.write(row, 6, chain.get('prot'))
        worksheet1.write(row, 7, chain.get('opt'))
        worksheet1.write(row, 8, chain.get('in'))
        worksheet1.write(row, 9, chain.get('out'))
        worksheet1.write(row, 10, chain.get('source'))
        worksheet1.write(row, 11, chain.get('destination'))
        worksheet1.write(row, 12, chain.get('xxx'))
        row += 1

workbook.close()

Во входных данных для последнего столбца некоторые строки не имеют значения.Конечно, эта ошибка вызвана этими пустыми пространствами, потому что я заполнил их чем-то случайным, и это сработало отлично.Мне нужно было бы сделать код как-то, чтобы игнорировать, если есть пустые места.

Ввод очень большой, но это шаблон файла.

---node1
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        1     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            
2       25  16K  ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            
3        7   28  ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:53
4       58  39K  ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            
5      81K  25M  ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
2        0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject

Chain OUTPUT (policy ACCEPT 398 packets, 23K bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1     2K      3M ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED

Есть ли способ добиться этого?PS Я использую Python 2.7

Большое спасибо заранее,

Romain

1 Ответ

0 голосов
/ 24 мая 2018

Во входных данных для последнего столбца некоторые строки не имеют значения.Конечно, эта ошибка вызвана этими пустыми пространствами, потому что я заполнил их чем-то случайным, и это сработало отлично.Мне нужно было бы как-то заставить код игнорировать, если есть пустые места.

Вы поймете, что python не может сообщить вам значение индекса 10, если такого индекса нет.Другими словами: вы находитесь в ресторане и обычно едите меню из пяти блюд.Официант дает только четыре, а потом спрашивает, как вам понравился пятый.На этот вопрос нет ответа.

Наиболее питонический способ решения этой проблемы - try и except:

# [...]
chain['source']=line.split()[8]
chain['destination']=line.split()[9]
try:
    chain['xxx']=line.split()[10]
except IndexError:
    pass # or do something else

Фактически, рассмотренное выше решение считаетсялучше проверить длину line и запретить переходить к пункту [10], если их недостаточно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...