更容易使用python作为awk的替代
awking的Python项目详细描述
awking
更容易使用python作为awk的替代。
基本用法
提取线组
fromawkingimportRangeGrouperlines='''text 1text 2group start 1text 3group end 1text 4group start 2text 5group end 2text 6'''.splitlines()forgroupinRangeGrouper('start','end',lines):print(list(group))
这将输出:
['group start 1', 'text 3', 'group end 1'] ['group start 2', 'text 5', 'group end 2']
提取固定宽度字段
fromawkingimportrecordsps_aux='''USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMANDroot 1 0.0 0.0 51120 2796 ? Ss Dec22 0:09 /usr/lib/systemd/systemd --system --deserialize 22root 2 0.0 0.0 0 0 ? S Dec22 0:00 [kthreadd]root 3 0.0 0.0 0 0 ? S Dec22 0:04 [ksoftirqd/0]root 5 0.0 0.0 0 0 ? S< Dec22 0:00 [kworker/0:0H]root 7 0.0 0.0 0 0 ? S Dec22 0:15 [migration/0]root 8 0.0 0.0 0 0 ? S Dec22 0:00 [rcu_bh]root 9 0.0 0.0 0 0 ? S Dec22 2:47 [rcu_sched]saml 3015 0.0 0.0 117756 596 pts/2 Ss Dec22 0:00 bashsaml 3093 0.9 4.1 1539436 330796 ? Sl Dec22 70:16 /usr/lib64/thunderbird/thunderbirdsaml 3873 0.0 0.1 1482432 8628 ? Sl Dec22 0:02 gvim -froot 5675 0.0 0.0 124096 412 ? Ss Dec22 0:02 /usr/sbin/crond -nroot 5777 0.0 0.0 51132 1068 ? Ss Dec22 0:08 /usr/sbin/wpa_supplicant -u -f /var/log/wpa_supplicasaml 5987 0.7 1.5 1237740 119876 ? Sl Dec26 14:05 /opt/google/chrome/chrome --type=renderer --lang=en-root 6115 0.0 0.0 0 0 ? S Dec27 0:06 [kworker/0:2]'''foruser,_,commandinrecords(ps_aux.splitlines(),widths=[7,58,...]):print(user,command)
这将输出:
USER COMMAND root /usr/lib/systemd/systemd --system --deserialize 22 root [kthreadd] root [ksoftirqd/0] root [kworker/0:0H] root [migration/0] root [rcu_bh] root [rcu_sched] saml bash saml /usr/lib64/thunderbird/thunderbird saml gvim -f root /usr/sbin/crond -n root /usr/sbin/wpa_supplicant -u -f /var/log/wpa_supplica saml /opt/google/chrome/chrome --type=renderer --lang=en- root [kworker/0:2]
问题
你有没有扫描过一个xmls的日志文件?对你来说有多难 将一组多行XML提取到单独的文件中?
您可以使用re.findall
或re.finditer
,但需要读取整个日志
先将文件放入字符串中。您也可以使用这样的awk脚本:
#!/usr/bin/awk -f/^Payload: <([-_a-zA-Z0-9]+:)?Request/{ofname="request_"(++index)".xml"sub(/^Payload: /,"")}/<([-_a-zA-Z0-9]+:)?Request/,/<\/([-_a-zA-Z0-9]+:)?Request/{print>ofname}/<\/([-_a-zA-Z0-9]+:)?Request/{if(ofname){close(ofname)ofname=""}}
这很管用,而且相当不错。(尽管这是一个python模块,我还是鼓励您 如果您还不知道awk,可以学习它。)
但是如果您想在python应用程序中构建这种东西呢? 如果输入的不是文件中的行,而是不同类型的对象,该怎么办?
使用awking
的python等价物
输入iterable中的RangeGrouper
类根据
开始和结束元素的谓词。这有点像Perl的范围
运算符或awk的范围模式,除了您的范围被分组到
START..END
可重复。
与上述awk脚本类似的脚本可能如下:
fromawkingimportRangeGrouperimportreimportsysg=RangeGrouper(r'^Payload: <([-_a-zA-Z0-9]+:)?Request',r'</([-_a-zA-Z0-9]+:)?Request',sys.stdin)forindex,requestinenumerate(g,1):withopen(f'request_{index}.xml','w')asf:forlineinrequest:line=re.sub(r'^Payload: ','',line)# Not optimalprint(line,file=f,end='')
谓词可以是正则表达式,作为re.compile()
对象或
字符串;或者它们可以是任何接受单个参数并返回
真/假值。
注意事项
分组算法惰性地读取输入iterable。你还可以跑出去 如果保留对以前组的引用而不使用它们,则会占用内存。