使用扩展Python超出范围

时间:2018-07-17 13:00:27

标签: python list

我试图从多台计算机访问“ df -T -k”命令输出的所有数据。我有以下输入:

---vm1 
Filesystem           Type      1K-blocks      Used Available Use% Mounted on
udev3                devtmpfs    7617616        12   7672731   1% /dev
tmpfs                tmpfs      19778012      5764  19772248   1% /run
/dev/dm-2            ext4       51474912   1921336  46915832   4% /
none                 tmpfs             4         0         4   0% /sys/fs/cgroup
/dev/sda3            ext2         200672     48808    141628  26% /boot
---vm2
Filesystem           Type   1K-blocks      Used Available Use% Mounted on
/dev/mapper/system-root
                     ext4  1419941428 387887564 959918392  29% /
tmpfs                tmpfs   99114124        64  99114060   1% /dev/shm
/dev/sda1            ext4      487652     78275    383777  17% /boot

为此,我尝试了以下代码:

word='Filesystem'

def create_chain(chain_segment):
    chains=[]
    chain_lines = [line for line in chain_segment.split('\n') if line]
    for line in chain_lines:
        chain={}
        a=line.split()[0]
        if not a.startswith('Filesystem'):
            chain['filesystem']=line.split()[0]
            chain['type']=line.split()[1]
            chain['1K-blocks']=line.split()[2]
            chain['used']=line.split()[3]
            chain['available']=line.split()[4]
            chain['use']=line.split()[5]
            chain['mounted']=line.split()[6]
        chains.append(chain)
    return chains

with open('/media/sf_vboxshared/diskusage.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

运行此代码后,出现以下错误:

Traceback (most recent call last):
  File "diskusage.py", line 33, in <module>
    chains.extend(create_chain(segment))
  File "diskusage.py", line 13, in create_chain
    chain['type']=line.split()[1]
IndexError: list index out of range

如果我尝试用line.split()打印每个单词并得到它们,但是似乎在for host循环中列表的扩展功能有问题。

有人知道为什么我的索引超出范围,应该如何纠正?

1 个答案:

答案 0 :(得分:1)

dt命令将为长度大于单词Filesystem的文件系统路径和一些空格(约18个字符)添加换行符。您的代码在这样的段上失败,该段上的文件系统字符串更长,而该行的其余部分打印在 next 行上:

Filesystem           Type   1K-blocks      Used Available Use% Mounted on
/dev/mapper/system-root
                     ext4  1419941428 387887564 959918392  29% /

因此对于该段中的第二行,line.split()恰好包含一个元素,文件系统字符串,而其他列都在下一行找到。

您必须检测出此类情况并进行处理:

def create_chain(chain_segment):
    chains = []
    keys = 'filesystem type 1K-blocks used available use mounted'.split()
    filesystem = None
    for line in chain_segment.splitlines():
        if not line or line.startswith('Filesystem'):
            # skip the header or any blank lines
            continue

        parts = line.split()
        if len(parts) == 1:
            # filesystem name is too long so this entry
            # is split across two lines. Remember the filesystem
            # name and move to the next line
            filesystem = parts[0]
            continue

        elif (len(parts) == 6 and line.startswith(' ') and 
              filesystem is not None):
            # the next line then has only 6 parts and starts with a space
            parts = [filesystem] + parts
            filesystem = None

        chains.append(dict(zip(keys, parts)))

    return chains

这可以解析任何一个段:

>>> segments = ['''\
... Filesystem           Type      1K-blocks      Used Available Use% Mounted on
... udev3                devtmpfs    7617616        12   7672731   1% /dev
... tmpfs                tmpfs      19778012      5764  19772248   1% /run
... /dev/dm-2            ext4       51474912   1921336  46915832   4% /
... none                 tmpfs             4         0         4   0% /sys/fs/cgroup
... /dev/sda3            ext2         200672     48808    141628  26% /boot
... ''', '''\
... Filesystem           Type   1K-blocks      Used Available Use% Mounted on
... /dev/mapper/system-root
...                      ext4  1419941428 387887564 959918392  29% /
... tmpfs                tmpfs   99114124        64  99114060   1% /dev/shm
... /dev/sda1            ext4      487652     78275    383777  17% /boot
... ''']
>>> from pprint import pprint
>>> for segment in segments:
...     pprint(create_chain(segment))
...
[{'1K-blocks': '7617616',
  'available': '7672731',
  'filesystem': 'udev3',
  'mounted': '/dev',
  'type': 'devtmpfs',
  'use': '1%',
  'used': '12'},
 {'1K-blocks': '19778012',
  'available': '19772248',
  'filesystem': 'tmpfs',
  'mounted': '/run',
  'type': 'tmpfs',
  'use': '1%',
  'used': '5764'},
 {'1K-blocks': '51474912',
  'available': '46915832',
  'filesystem': '/dev/dm-2',
  'mounted': '/',
  'type': 'ext4',
  'use': '4%',
  'used': '1921336'},
 {'1K-blocks': '4',
  'available': '4',
  'filesystem': 'none',
  'mounted': '/sys/fs/cgroup',
  'type': 'tmpfs',
  'use': '0%',
  'used': '0'},
 {'1K-blocks': '200672',
  'available': '141628',
  'filesystem': '/dev/sda3',
  'mounted': '/boot',
  'type': 'ext2',
  'use': '26%',
  'used': '48808'}]
[{'1K-blocks': '1419941428',
  'available': '959918392',
  'filesystem': '/dev/mapper/system-root',
  'mounted': '/',
  'type': 'ext4',
  'use': '29%',
  'used': '387887564'},
 {'1K-blocks': '99114124',
  'available': '99114060',
  'filesystem': 'tmpfs',
  'mounted': '/dev/shm',
  'type': 'tmpfs',
  'use': '1%',
  'used': '64'},
 {'1K-blocks': '487652',
  'available': '383777',
  'filesystem': '/dev/sda1',
  'mounted': '/boot',
  'type': 'ext4',
  'use': '17%',
  'used': '78275'}]