简体   繁体   中英

Linux command out put into dictionary - python

Below example I took it from a website to parse vmstat in one line,

vmstat | python -c 'import sys; print dict(zip(*map(str.split, sys.stdin)[-2:])).get("id")'

92

However I am trying to use this into the code rather then one line. , but I am unable to get the dictionary value. its alwasy NONE

    import os
    import sys
    import subprocess
    mydict = {}
    cmd = subprocess.Popen('vmstat',stdout=subprocess.PIPE)
    msg,err = cmd.communicate()
    mydict= zip(*map(str.split, msg)[-2:])
    print mydict

Can any one please help me to get dictionary value right ?

Thanks fo the help

It seems that you to take care of \\n character. I've tried this snipped

>>> dict(zip(*map(str.split, msg.split("\n")[1:-1])))
{'wa': '0', 'sy': '1', 'b': '0', 'us': '5', 'bo': '34', 'cache': '872064', 'bi': '150', 'free': '5786860', 'st': '0', 'si': '0', 'r': '2', 'so': '0', 'swpd': '0', 'in': '167', 'cs': '647', 'id': '93', 'buff': '52920'}

Now a slow motion script:

#split by whitespace (default) all lines unless the first (vmstat caption) and the last one (the last return)
>>> map(str.split, msg.split("\n")[1:-1])
[['r', 'b', 'swpd', 'free', 'buff', 'cache', 'si', 'so', 'bi', 'bo', 'in', 'cs', 'us', 'sy', 'id', 'wa', 'st'], ['2', '0', '0', '5786860', '52920', '872064', '0', '0', '150', '34', '167', '647', '5', '1', '93', '0', '0']]

#create a list of tuples key-value of the previous output
>>> zip(*map(str.split, msg.split("\n")[1:-1]))
[('r', '2'), ('b', '0'), ('swpd', '0'), ('free', '5786860'), ('buff', '52920'), ('cache', '872064'), ('si', '0'), ('so', '0'), ('bi', '150'), ('bo', '34'), ('in', '167'), ('cs', '647'), ('us', '5'), ('sy', '1'), ('id', '93'), ('wa', '0'), ('st', '0')]

#pass that list of tuples to dict function
>>> dict(zip(*map(str.split, msg.split("\n")[1:-1])))
{'wa': '0', 'sy': '1', 'b': '0', 'us': '5', 'bo': '34', 'cache': '872064', 'bi': '150', 'free': '5786860', 'st': '0', 'si': '0', 'r': '2', 'so': '0', 'swpd': '0', 'in': '167', 'cs': '647', 'id': '93', 'buff': '52920'}

We skip the first line and split to get items.
Try this:

import os
import sys
import subprocess
mydict = {}
cmd = subprocess.Popen('vmstat',stdout=subprocess.PIPE)
msg,err = cmd.communicate()
#we use `-1` index because last element is an empty list
lst = [item.split() for item in msg.split('\n')[1:-1]]
mydict= {k:v for k, v in zip(*map(list, lst))}

print mydict.get('id')

Let's examine what's happening here:

msg,err = cmd.communicate() , will return to you the message strings from executing vmstat command (output and error msg if any), so in my try:

>>>print `msg` 
[0]procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
[1] r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
[2] 1  0 194776  69880  31716 207876    0    0     4     4    4   51  2  0 98  0  0

(I've added [0],[1] &[2] to futher reference line number below, it's not part of print msg )

Now, if you do map(str.split, msg) this will split all the msg into a list of of list of single character, So you should first split over '\\n' . This will give you a list of strings (separate lines if you want), then apply zip with str.split over the two lines([1] & [2]) to take a key from line [1] and a value from line [2], this way:

mylist = msg.split('\n')[1:3] #line [1] & [2]
mydict = dict(zip(*map(str.split, mylist)))

This should get you a dictionary with keys from line[1] and values from line[2]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM