Python第十二天 收集主機信息 正則表達式 正則表達式 無名分組 有名分組
目錄
Python第二天 變量 運算符與表達式 input()與raw_input()區別 字符編碼
Python第三天 序列 數據類型 數值 字符串 列表 元組 字典
Python第四天 流程控制 ifelse條件判斷 forwhile循環
Python第五天 文件訪問 for循環訪問文件 while循環訪問文件 字符串的startswith函數和split函數
Python第七天 函數 函數參數 函數變量 函數返回值 多類型傳值 冗余參數 函數遞歸調用 匿名函數 內置函數 列表表達式/列表重寫
Python第八天 模塊 包 全局變量和內置變量__name__ Python path
Python第九天 面向對象 類定義 類的屬性 類的方法 內部類 垃圾回收機制 類的繼承
Python第十天 print >> f,和fd.write()的區別 stdout的buffer 標準輸入 標準輸出 標準錯誤 重定向
Python第十二天 收集主機信息 正則表達式 正則表達式 無名分組 有名分組
Python第十四天 序列化 pickle模塊 cPickle模塊 JSON模塊 API的兩種格式
收集主機信息
1. 主機名:hostname
2. IP地址:ip
3. 操作系統版本:osver
4. 服務器廠商:vendor
5. 服務器型號:product
6. 服務器序列號:sn
7. cpu型號:cpu_model
8. cpu核數:cpu_num
9. 內存大小:memory
python中,platform模塊給我們提供了很多方法去獲取操作系統的信息
示例1 #!/usr/bin/env python from subprocess import Popen, PIPE p = Popen(['dmidecode'], stdout=PIPE) data = p.stdout # 從標準輸出讀取 返回一個文件對象 lines = [] dmi = {} a = True while a: line = data.readline() if line.startswith('System Information'): while True: line = data.readline() if line == '\n': # 如果讀到空行,那么結束讀取,整行就有一個換行符就是空行\n a = False # 退出外層循環 break else: lines.append(line) dmi_dic = dict([i.strip().split(':') for i in lines]) # 將列表變為字典 dmi['Manufacturer'] = dmi_dic['Manufacturer'].strip() dmi['Product'] = dmi_dic['Product Name'].strip() dmi['Serial'] = dmi_dic['Serial Number'].strip() print dmi
示例2 #!/usr/bin/env python from subprocess import Popen, PIPE def getDmi(): p = Popen(['dmidecode'], stdout=PIPE) data = p.stdout.read() return data def parseDmi(data): lines = [] line_in = False dmi_list = [i for i in data.split('\n') if i] for line in dmi_list: if line.startswith('System Information'): line_in = True continue if line_in: if not line[0].strip(): lines.append(line) else: break return lines def dmiDic(): dmi_dic = {} data = getDmi() lines = parseDmi(data) dic = dict([i.strip().split(': ') for i in lines]) dmi_dic['vendor'] = dic['Manufacturer'] dmi_dic['product'] = dic['Product Name'] dmi_dic['sn'] = dic['Serial Number'] return dmi_dic if __name__ == '__main__': print dmiDic()
在Python里,以下這些對象相當于布爾值的False
空列表([] )
空元組(() )
空字典({} )
空字符串('' )
零值(0 )
特殊對象None
對象False
獲取網卡信息示例1 #!/usr/bin/env python from subprocess import Popen, PIPE def getIfconfig(): p = Popen(['ifconfig'], stdout=PIPE) data = p.stdout.read().split('\n\n') return [i for i in data if i and not i.startswith('lo')] def parseIfconfig(data): dic = {} for lines in data: line_list = lines.split('\n') devname = line_list[0].split()[0] macaddr = line_list[0].split()[-1] ipaddr = line_list[1].split()[1].split(':')[1] dic[devname] = [ipaddr, macaddr] return dic if __name__ == '__main__': data = getIfconfig() print parseIfconfig(data)
獲取網卡信息示例2 #!/usr/bin/env python from subprocess import Popen, PIPE def getIP(): p = Popen(['ifconfig'], stdout=PIPE, stderr=PIPE) stdout, stderr = p.communicate() data = [i for i in stdout.split('\n') if i] return data def genIP(data): new_line = '' lines = [] for line in data: if line[0].strip(): lines.append(new_line) new_line = line + '\n' else: new_line += line + '\n' lines.append(new_line) return [i for i in lines if i and not i.startswith('lo')] def parseIfconfig(data): dic = {} for lines in data: line_list = lines.split('\n') devname = line_list[0].split()[0] macaddr = line_list[0].split()[-1] ipaddr = line_list[1].split()[1].split(':')[1] dic[devname] = [ipaddr, macaddr] return dic if __name__ == '__main__': data = getIP() data_list = genIP(data) print parseIfconfig(data_list)
#!/usr/bin/env python import re from subprocess import Popen, PIPE def getIfconfig(): p = Popen(['ifconfig'], stdout=PIPE) data = p.stdout.read().split('\n\n') return [i for i in data if i and not i.startswith('lo')] def parseIfconfig(data): re_devname = re.compile(r'(br|eth|em|virbr|lo|bond)[\d:]+',re.M) re_mac = re.compile(r'HWaddr ([0-9A-F:]{17})', re.M) re_ip = re.compile(r'inet addr:([\d\.]{7,15})', re.M) devname = re_devname.search(data) if devname: devname = devname.group() else: devname = '' mac = re_mac.search(data) if mac: mac = mac.group(1) else: mac = '' ip = re_ip.search(data) if ip: ip = ip.group(1) else: ip = '' return {devname: [ip, mac]} if __name__ == '__main__': dic = {} data = getIfconfig() for i in data: dic.update(parseIfconfig(i)) print dic
---------------------------------------------------------------
正則表達式
re模塊(標準庫里面)
分析日志、提取信息
普通字符
元字符: .、^、$、*、+、?、{}、[]、\ 轉義、|、()
\d: 匹配任何十進制數,相當于[0-9]
\D: 匹配任何非數字字符,相當于[^0-9]
\s: 匹配任何空白字符,相當于[\t\n\r\f\v]
\S: 匹配任何非空白字符,相當于[^\t\n\r\f\v]
\w: 匹配任何字母數字字符,相當于[a-zA-Z0-9],包括下劃線等特殊符號
\W: 匹配任何非字母數字字符,相當于[^a-zA-Z0-9]
findall(pattern, string, flags=0)
flags:指定匹配的模式,比如re.S匹配空字符
re.findall(r'.','ab\nss',re.S)
['a', 'b', '\n', 's', 's']
正則方法
re.findall()方法:找到re匹配的所有子串,并把它作為一個列表返回,如果用到()元字符只返回()里的內容這時候要用search的group方法
re.match()方法:返回一個對象,只匹配開始的位置
text = ‘hello world ’
m = re.match(r’(\w+)\s’, text)
m.group() 等價于 m.group(0) 整行數據
m.group(1) 打印第一組
按照括號分的,第一個括號是group(1),第二個括號是group(2)
re.sub()方法:替換
re.sub('he' ,'HE' ,'hellohe',count=2)
re.sub(old ,'new ,字符串,替換的次數)
re.search()方法:從左到右掃描字符串,直到找到第一個re匹配的字符串就停止,不會再匹配后面的即使后面也有匹配字符串
re.match與re.search的區別:re.match只匹配字符串的開始,如果成功的話,返回MatchObject實例,
如果字符串開始不符合正則表達式,則匹配失敗,函數返回None;
而re.search匹配整個字符串,直到找到一個匹配,如果成功的話,返回MatchObject實例
compile():將正則表達式編譯成對象,并用他們來進行匹配,compile(正則表達式)
p = re.compile(r'ab*')
p = re.compile(r'ab*',re.I|re.S|re.M)
p.findall('G\nd')
>>> import re
>>> p = re.compile(r'ab*') #正則表達式
>>> p
<_sre.SRE_Pattern object at 0x7fa2c0deb960>
s = ‘abc’
p.findall(s) # 匹配ab* 正則
或:
reg = r’ab*’
re.findall(reg, s)
標志flags
re.I 對應2
re.IGNORECASE 忽略大小寫
re.L 對應4
re.LOCALE
re.M 對應8
re.MULTILINE 多行匹配
re.S 對應16 使.匹配包括換行符在內的所有字符
re.Scanner 包括換行符
re.T 對應1
re.TEMPLATE 模板匹配
re.U 對應32
re.UNICODE 包含unicode字符
re.X 對應64 正則可以使用多行來寫
re.S和re.I
s = 'god GOD G\nd'
re.findall(r'g.d',s ,re.S|re.I)
re.M
data = open('/etc/passwd').read()
ftp = re.compile(r'(^ftp)',re.M)
ftp.findall(data)
a = ftp.search(data)
a.group()
示例1
>>> smail = "root@123.com"
>>> rmail = r'[\w_]+@\w+\.[a-zA-Z]{2,3}‘
>>> re.findall(rmail, smail)
>>> rmail = r"""[0-9a-zA-Z_]+
... @
... [0-9a-zA-Z]+
... \.
... [a-zA-Z]{2,3}
... ""“
>>> re.findall(rmail,smail,re.X)
re.X:正則可以使用多行來寫
greedy模式 greedy貪婪 貪婪匹配
?:抑制貪婪
>>> ss = '<h1> hello </h1>‘
>>> re.findall(r'<.*>', ss)
['<h1> hello </h1>']
>>> re.findall(r'<.*?>', ss)
['<h1>', '</h1>']
syslog reg
reg_syslog = re.compile(r'\w+ \d+ [\d:]+ [\w\d.]+ \w+(\[\d+\])?: .*')
ss = 'Nov 21 14:52:23 localhost dhclient[1005]: bound to 192.168.3.163 -- renewal in 2843 seconds.'
s = reg_syslog.search(ss) # 不能用findall,因為用到了()元字符
s.group()
無名分組:沒有定義別名的分組,訪問的時候使用數字來訪問,s.group(1)
有名分組:
(?P<name>...)
REG_LOG = re.compile(r'(?P<logtime>\w+ \d+ [\d:]+) (?P<hostname>[\w\d.]+) (?P<programe>\w+(\[\w+\])?:) (?P<msg>.*)')
s = REG_LOG.search(ss)
s.groupdict() #返回一個字典
/var/log/message有四個部分
1、時間戳
2、主機名,由哪臺主機產生的日志,有些主機名是用FQDN的形式
3、進程名,一般包含pid
4、具體日志信息
# 收集主機信息 # collect_info.py #!/usr/bin/env python import urllib, urllib2 from subprocess import Popen, PIPE import pickle def getIfconfig(): p = Popen(['ifconfig'], stdout=PIPE) data = p.stdout.read() return data def getDmi(): p = Popen(['dmidecode'], stdout=PIPE) data = p.stdout.read() return data def parseData(data): parsed_data = [] new_line = '' data = [i for i in data.split('\n') if i] for line in data: if line[0].strip(): parsed_data.append(new_line) new_line = line+'\n' else: new_line += line+'\n' parsed_data.append(new_line) return [i for i in parsed_data if i] def parseIfconfig(parsed_data): dic = {} parsed_data = [i for i in parsed_data if not i.startswith('lo')] for lines in parsed_data: line_list = lines.split('\n') devname = line_list[0].split()[0] macaddr = line_list[0].split()[-1] ipaddr = line_list[1].split()[1].split(':')[1] break dic['ip'] = ipaddr return dic def parseDmi(parsed_data): dic = {} parsed_data = [i for i in parsed_data if i.startswith('System Information')] parsed_data = [i for i in parsed_data[0].split('\n')[1:] if i] dmi_dic = dict([i.strip().split(':') for i in parsed_data]) dic['vendor'] = dmi_dic['Manufacturer'].strip() dic['product'] = dmi_dic['Product Name'].strip() dic['sn'] = dmi_dic['Serial Number'].strip()[:15] return dic def getHostname(f): with open(f) as fd: for line in fd: if line.startswith('HOSTNAME'): hostname = line.split('=')[1].strip() break return {'hostname':hostname} # 返回一個字典 def getOSver(f): with open(f) as fd: for line in fd: osver = line.strip() break return {'osver':osver} def getCpu(f): num = 0 with open(f) as fd: for line in fd: if line.startswith('processor'): num += 1 if line.startswith('model name'): cpu_model = line.split(':')[1].split() cpu_model = cpu_model[0]+' '+cpu_model[-1] return {'cpu_num':num, 'cpu_model':cpu_model} def getMemory(f): with open(f) as fd: for line in fd: if line.startswith('MemTotal'): mem = int(line.split()[1].strip()) break mem = "%s" % int(mem/1024.0)+'M' return {'memory':mem} if __name__ == '__main__': dic = {} data_ip = getIfconfig() parsed_data_ip = parseData(data_ip) ip = parseIfconfig(parsed_data_ip) data_dmi = getDmi() parsed_data_dmi = parseData(data_dmi) dmi = parseDmi(parsed_data_dmi) hostname = getHostname('/etc/sysconfig/network') osver = getOSver('/etc/issue') cpu = getCpu('/proc/cpuinfo') mem = getMemory('/proc/meminfo') dic.update(ip) dic.update(dmi) dic.update(hostname) dic.update(osver) dic.update(cpu) dic.update(mem) print dic #d = urllib.urlencode(dic) d = pickle.dumps(dic) req = urllib2.urlopen('http://192.168.1.5:8000/hostinfo/collect/',d) print req.read() # 收集主機信息 正則表達式版本 #!/usr/bin/env python import re from subprocess import Popen, PIPE def getIfconfig(): p = Popen(['ifconfig'], stdout=PIPE) data = p.stdout.read().split('\n\n') return [i for i in data if i and not i.startswith('lo')] def parseIfconfig(data): re_devname = re.compile(r'(br|eth|em|virbr|lo|bond)[\d:]+',re.M) re_mac = re.compile(r'HWaddr ([0-9A-F:]{17})', re.M) re_ip = re.compile(r'inet addr:([\d\.]{7,15})', re.M) devname = re_devname.search(data) if devname: devname = devname.group() else: devname = '' mac = re_mac.search(data) if mac: mac = mac.group(1) else: mac = '' ip = re_ip.search(data) if ip: ip = ip.group(1) else: ip = '' return {devname: [ip, mac]} if __name__ == '__main__': dic = {} data = getIfconfig() for i in data: dic.update(parseIfconfig(i)) print dic
# group示例 # 按照括號分的,第一個括號是group(1),第二括號是group(2),以此類推。 group(0)與group()相同,表示匹配到的內容。 In [35]: m = re.match(r'(\w+)\s(\w+)\s', 'hello world abc') In [36]: m.group() Out[36]: 'hello world ' In [37]: m.group(0) Out[37]: 'hello world ' In [38]: m.group(1) Out[38]: 'hello' In [39]: m.group(2) Out[39]: 'world'
文章列表
| 不含病毒。www.avast.com |
