2015-05-25 113 views
0

我發現了一些python代碼來解析下面的linux命令'vmstat'的輸出。解析vmstat python代碼解釋

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

vmstat 
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---- 
r b swpd free buff cache si so bi bo in cs us sy id wa 
11 0 385372 101696 61704 650716 0 1  5  9 6 12 5 2 92 0 

我在想,如果有人能向我解釋什麼代碼做特別的(郵政編碼(*地圖(str.split,sys.stdin) - 2:])部分

表示感謝?你

+1

你應該分解每一步,看看每個返回的結果 –

+1

我會選擇awk來避免所有這些模棱兩可的問題:'vmstat | awk'{print $ 6}''。 – HuStmpHrrr

回答

1

這是一些聰明的代碼,但有點太聰明

讓我們分解: 字典(郵政編碼(*地圖(str.split,sys.stdin) - 2:]))

第一部歌劇將會是: map(str.split,sys.stdin)

Map將作爲其第一個參數的函數應用於其第二個參數的iterable的每個元素。 (如果第二個參數不是可迭代的,它將被作爲一個給予可迭代的結果)。 例如,這裏:

>>> map (int, ["1", "2", "3"]) 
[1, 2, 3] 

>>> (int, "1") 
[1] 

所以在這裏,該第一表達式可以讀作: 「標準輸入應用str.split」(sys.stdin)。

該第一操作的結果是很容易檢查:

vmstat | python -c 'import sys; print (map(str.split, sys.stdin))' 

[['procs', '-----------memory----------', '---swap--', '-----io----', '-system--', '----cpu----'], ['r', 'b', 'swpd', 'free', 'buff', 'cache', 'si', 'so', 'bi', 'bo', 'in', 'cs', 'us', 'sy', 'id', 'wa'], ['1', '0', '490952', '155924', '437356', '2064528', '0', '0', '3', '59', '0', '1', '6', '1', '91', '2']] 

標準輸入爲3線的陣列。每一行都使用默認的拆分操作進行拆分,因此每個元素都可以很好地進行分析。現在,我們不需要第一行,所以我們只需要數組的最後兩行,因此[-2:]。再次,這是經典的Python:

>>> a = [1,2,3,4] 
>>> a[-2:] 
[3,4] 

因此,我們有大小2的名單列表的第一個列表與鍵行,第二個列表是與相應的值就行了。這看起來像一本字典,不是嗎?但它還不是。我們需要字典,爲此。 快譯通是有幾個構造函數,它們是一個類型:

help(dict) 
[...] 
| dict(mapping) -> new dictionary initialized from a mapping object's 
|  (key, value) pairs 
[...] 

所以,如果我輸入:

dict([('name', 'john'), ('profession', 'computer scientist')]) 

我得到:

{'name': 'john', 'profession': 'computer scientist'} 

,但我們不有一個元組列表[(key,value)],我們有一個列表[[key,key,key ...],[value,value,value ...]]。

獲取元組列表的一種方法是使用zip函數。

>>> k = ['key1', 'key2', 'key3'] 
>>> v = ['value1', 'value2', 'value3'] 
>>> zip(k,v) 
[('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3')] 

而壓縮的結果是我們可以用來建立一個字典! 但是我們沒有兩個單獨的迭代器k和v,在這裏。我們只有一份清單!所以這裏還有另一個技巧:將參數作爲列表傳遞。這是記錄在這裏: https://docs.python.org/2/tutorial/controlflow.html#unpacking-argument-lists

的想法是,如果你有一個函數,X參數,你可以給他們明確地,像這樣:

def fun(a,b): 
    return a + b 

fun(2,3) 

但你也可以用一個列表給他們打電話,使用*語法,如下所示:

fun(*[2,3]) 

「*」符號表示:「解包列表中的所有內容到每個參數」。需要注意的是,如果我做的:

fun(*[2,3,4]) 

它會失敗,就像我想:

fun(2,3,4) 

因爲好玩只想要2個參數。因此,在這裏,我們的列表[[key,key ...],[value,value]]將被提供給解壓縮的zip,所以真正的調用是zip([key,key ...],[value,value ..] 。])...這給了我們想要的東西,一本字典。在這本詞典中,我們只需使用鍵「緩存」即可獲得該值。我們完成了。

雖然這一行內容很聰明,但並不令人愉快。 HuStmpHrrr在這個問題的評論中提供了一個更好的方法。

+0

謝謝Raveline爲您提供非常詳細的解釋。 – scalauser