天天看点

python 脚本学习(一)

日志读取脚本

功能:用于读取某日志文件,可指定某个匹配条件,返回文本中匹配到的该行和前面的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 -&gt; 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 =&gt; %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 =&gt; %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