日志讀取腳本
功能:用于讀取某日志檔案,可指定某個比對條件,傳回文本中比對到的該行和前面的n行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<code>此腳本可以接受</code><code>3</code><code>個參數,分别是檔案對象、搜尋的關鍵詞、傳回比對的該行前面的行數。</code>
<code>#!/usr/local/python27/bin/python2.7</code>
<code>import</code> <code>sys</code>
<code>from</code> <code>collections </code><code>import</code> <code>deque</code>
<code>def</code> <code>search(f,pattern,keep_num):</code>
<code>#定義一個隊列,設定最大隊列數,這個隊列中的資料是可覆寫的,如果達到了最大隊列數,則新加入的資料會覆寫前面的。</code>
<code> </code><code>pre_lines </code><code>=</code> <code>deque(maxlen</code><code>=</code><code>keep_num)</code>
<code> </code><code>for</code> <code>line </code><code>in</code> <code>f:</code>
<code> </code><code>if</code> <code>pattern </code><code>in</code> <code>line:</code>
<code> </code><code>yield</code> <code>line,pre_lines</code>
<code>#這裡的邏輯就是将從檔案對象f中讀取的每一行做模式比對的判斷,如果不比對則放入pre_lines隊列中去,繼續查找下一行,隻儲存最大能允許的行數,這個有參數maxlen控制,多出的資料則覆寫前面的,直到比對到了需要的關鍵字,則傳回一個生成器,生成器中包括了比對到的行,以及該行之前的n行,也就是之前儲存在pre_lines隊列中的行。 </code>
<code> </code><code>pre_lines.append(line)</code>
<code>if</code> <code>__name__ </code><code>=</code><code>=</code> <code>'__main__'</code><code>:</code>
<code> </code><code>log_file </code><code>=</code> <code>sys.argv[</code><code>1</code><code>]</code>
<code> </code><code>pattern </code><code>=</code> <code>sys.argv[</code><code>2</code><code>]</code>
<code> </code><code>keep_num </code><code>=</code> <code>int</code><code>(sys.argv[</code><code>3</code><code>])</code>
<code> </code><code>with </code><code>open</code><code>(log_file) as f:</code>
<code>#這個循環就是從search函數傳回的生成器中取資料,分别儲存在變量中,再分别列印出來。 </code>
<code> </code><code>for</code> <code>line,pre_lines </code><code>in</code> <code>search(f,pattern,keep_num):</code>
<code> </code><code>for</code> <code>pline </code><code>in</code> <code>pre_lines:</code>
<code> </code><code>print</code> <code>pline</code>
<code> </code><code>print</code> <code>line</code>
<code> </code><code>print</code> <code>"-"</code> <code>*</code> <code>20</code>
鍵值對處理腳本
處理一個key -> value的配置檔案,key可能出現多次,對應相同或者不同的value,要求傳回每個key對應的所有不重複的value。
這裡先講下collections子產品的defaultdict 和 dict
這裡的defaultdict(function_factory)建構的是一個類似dictionary的對象,其中keys的值,自行确定指派,但是values的類型,是function_factory的類執行個體,而且具有預設值。比如default(int)則建立一個類似dictionary對象,裡面任何的values都是int的執行個體,而且就算是一個不存在的key, d[key] 也有一個預設值,這個預設值是int()的預設值0.
筆者的了解:
defaultdict接受一個工廠函數作為參數,這個傳入的工廠函數的類型,決定了該字典對象中keys的類型和值的類型。
比如 defaultdict(set)這裡傳入了一個set類型,這表示其中的keys為集合,要在key中加入資料則要使用集合的内置add方法,對應的value也會符合集合的特點,無序性,唯一性。
如果 defaultdict(list) 這裡傳入了一個list類型,這表示其中的keys為清單,要在key中加入資料則要使用清單的内置方法append,對應的value也會符合清單的特點,有序性,可重複。
處理如下檔案:
key1=111
key2=222
key1=123
key3=333
key4=111
key5=555
key6=666
key7=777
key8=111
要實作傳回每個key對應的所有不重複的value,這裡要使用set類型。
代碼執行個體:
<code>!</code><code>/</code><code>usr</code><code>/</code><code>local</code><code>/</code><code>python27</code><code>/</code><code>bin</code><code>/</code><code>python2.</code><code>7</code>
<code>from</code> <code>collections </code><code>import</code> <code>defaultdict</code>
<code>conf </code><code>=</code> <code>defaultdict(</code><code>set</code><code>)</code>
<code>for</code> <code>line </code><code>in</code> <code>open</code><code>(sys.argv[</code><code>1</code><code>]):</code>
<code> </code><code>k,v </code><code>=</code> <code>line.split(</code><code>'='</code><code>)</code>
<code>#由于傳入的工廠函數為set,是以這裡的key就是集合,要用集合的add方法插入值。</code>
<code> </code><code>conf[k.strip()].add(v.strip()) </code>
<code>for</code> <code>k,v </code><code>in</code> <code>conf.items():</code>
<code> </code><code>print</code> <code>"%s => %s"</code> <code>%</code> <code>(k,v)</code>
輸出結果:
<a href="http://s3.51cto.com/wyfs02/M00/72/65/wKiom1XilAuQZAu0AAC9tahbXi0683.jpg" target="_blank"></a>
可以觀察到文本中有多個重複的key1=111隻輸出了一次。
下面傳入list類型做對比
<a href="http://s3.51cto.com/wyfs02/M00/72/61/wKioL1XimBawg5RWAADGd4vyXYI244.jpg" target="_blank"></a>
有一些任務,需要儲存到字典中,key為名稱,value為内容,但是在執行的時候,需要保持存儲時的順序。
方法(一)
使用字典儲存資料,并附加一個list儲存順序
<code>d1</code><code>=</code><code>dict</code><code>()</code>
<code>l1</code><code>=</code><code>[]</code>
<code> </code><code>l1.append(k)</code>
<code> </code><code>d1[k] </code><code>=</code> <code>v</code>
<code>print</code><code>(</code><code>"%s => %s"</code> <code>%</code> <code>( [ i </code><code>for</code> <code>i </code><code>in</code> <code>l1],[ d1[i] </code><code>for</code> <code>i </code><code>in</code> <code>l1 ]))</code>
方法(二)
使用OrderedDict
<code>from</code> <code>collections </code><code>import</code> <code>OrderedDict</code>
<code>od </code><code>=</code> <code>OrderedDict()</code>
<code> </code><code>od[k.strip()] </code><code>=</code> <code>v.strip()</code>
<code>for</code> <code>k,v </code><code>in</code> <code>od.items():</code>
<code> </code><code>print</code> <code>k,v</code>
一般字典dict()是無序的,但是OrderedDict是有序字典,會按照插入的順序儲存資料。
從一篇英文文章中統計出頻率出現最高的10個單詞
<code>import</code> <code>re</code>
<code>from</code> <code>collections </code><code>import</code> <code>Counter</code>
<code>with </code><code>open</code><code>(sys.argv[</code><code>1</code><code>]) as f:</code>
<code>#比對出是以單詞,并且全部轉換為小寫,儲存在一個清單中。</code>
<code> </code><code>words </code><code>=</code> <code>re.findall(r</code><code>"\w+"</code><code>,f.read().lower())</code>
<code>#Counter方法可以從一個清單中統計每個元素出現的次數,.most_common(n)用于篩選出出現次數最多n項;</code>
<code> </code><code>print</code> <code>Counter(words).most_common(</code><code>10</code><code>)</code>
./counter.py english_article.txt
[('to', 16), ('his', 15), ('him', 12), ('in', 12), ('tyler', 9), ('she', 9), ('and', 9), ('that', 8), ('he', 8), ('i', 8)
使用命名元組分段處理一個csv的檔案
檔案樣例:
name,gender,email,phone,sn
huairen,man,[email protected],1899000001,17829
<code>import</code> <code>csv</code>
<code>from</code> <code>collections </code><code>import</code> <code>namedtuple</code>
<code>with </code><code>open</code><code>(sys.argv[</code><code>1</code><code>],</code><code>'rb'</code><code>) as f:</code>
<code> </code><code>reader </code><code>=</code> <code>csv.reader(f)</code>
<code> </code><code>nametup </code><code>=</code> <code>namedtuple(</code><code>"tup"</code><code>,reader.</code><code>next</code><code>())</code>
<code> </code><code>for</code> <code>line </code><code>in</code> <code>reader:</code>
<code> </code><code>l1.append(nametup(</code><code>*</code><code>line))</code>
<code> </code><code>print</code><code>(l1)</code>
命名元組的使用執行個體:
<a href="http://s3.51cto.com/wyfs02/M02/72/98/wKioL1XoTA-jphS9AADfRrnHEvM433.jpg" target="_blank"></a>
tup(name='huairen', gender='man', email='[email protected]', phone='1899000001', sn='17829')
本文轉自qw87112 51CTO部落格,原文連結:http://blog.51cto.com/tchuairen/1689877