博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python awk_如何将awk脚本移植到Python
阅读量:2527 次
发布时间:2019-05-11

本文共 6050 字,大约阅读时间需要 20 分钟。

python awk

脚本是重复解决问题的有效方法,而awk是编写脚本的出色语言。 它特别擅长于简单的文本处理,并且可以带您完成配置文件的某些复杂重写或目录中文件名的重新格式化。

何时从awk移至Python

但是到了某个时候,awk的局限性开始显现出来。 它没有将文件分解为模块的实际概念,它没有质量错误报告,并且缺少了现在被认为是语言工作原理的其他内容。 当编程语言的这些丰富功能有助于维护关键脚本时,移植将是一个不错的选择。

我最喜欢的完美移植awk的现代编程语言是Python。

在仔细考虑了上下文并确定了要用Python替代的东西之后,该编写代码了。

标准awk到Python功能

要记住以下Python功能:

with      
open
( some_file_name
)
as fpin:
   
for line
in fpin:
       
pass
# do something with line

此代码将逐行循环遍历文件并处理这些行。

如果要访问行号(相当于awk的NR ),则可以使用以下代码:

with      
open
( some_file_name
)
as fpin:
   
for nr
, line
in
enumerate
( fpin
) :
       
pass
# do something with line

Python中多个文件的类似awk的行为

如果您需要能够遍历任意数量的文件同时保持行数的持久计数(例如awk的FNR ),则此循环可以做到这一点:

def awk_like_lines      
( list_of_file_names
) :
   
def _all_lines
(
) :
       
for filename
in list_of_file_names:
           
with
open
( filename
)
as fpin:
               
yield
from fpin
   
yield
from
enumerate
( _all_lines
(
)
)

该语法使用Python的生成器yield from构建遍历所有行并保持持久计数的迭代器

如果您需要FNRNR等效,这是一个更复杂的循环:

def awk_like_lines      
( list_of_file_names
) :
   
def _all_lines
(
) :
       
for filename
in list_of_file_names:
           
with
open
( filename
)
as fpin:
               
yield
from
enumerate
( fpin
)
   
for nr
,
( fnr
, line
)
in _all_lines:
       
yield nr
, fnr
, line

具有FNR,NR和线路的更复杂的awk功能

问题是否仍然存在,是否需要全部三个: FNRNRline 。 如果确实如此,则使用三元组(其中两个项目是数字)会引起混乱。 命名参数可使该代码更易于阅读,因此最好使用dataclass

import dataclass     
@ dataclass.
dataclass
( frozen
=
True
)
class AwkLikeLine:
    content:
str
    fnr:
int
    nr:
int
def awk_like_lines
( list_of_file_names
) :
   
def _all_lines
(
) :
       
for filename
in list_of_file_names:
           
with
open
( filename
)
as fpin:
               
yield
from
enumerate
( fpin
)
   
for nr
,
( fnr
, line
)
in _all_lines:
       
yield AwkLikeLine
( nr
= nr
, fnr
= fnr
, line
= line
)

您可能想知道,为什么不从这种方法开始呢? 从其他地方开始的原因是,这几乎总是太复杂了。 如果您的目标是使通用库更容易将awk移植到Python,请考虑这样做。 但是编写一个可以使您确切地了解特定情况所需的循环的方法通常更容易实现,也更容易理解(因而易于维护)。

了解awk字段

一旦拥有与一行相对应的字符串,如果要转换awk程序,则通常需要将其分解为field 。 Python有几种方法可以做到这一点。 这将返回一个字符串列表,将行分割为任意数量的连续空格:

line. split ( )

如果需要另一个字段分隔符,则类似这样的行将用分隔; 需要rstrip方法来删除最后一个换行符:

line. rstrip ( " \n " ) . split ( ":" )

完成以下操作后,列表部分将具有分解字符串:

parts = line. rstrip ( " \n " ) . split ( ":" )

这种拆分非常适合选择如何处理参数,但是我们处于一个情形中。 现在, parts [0]将对应于awk的$ 1parts [1]将对应于awk的$ 2 ,依此类推。这是因为awk从1开始计数“字段”,而Python从0开始计数。在awk的$ 0中是整行-等效于line.rstrip(“ \ n”)   并且awk的NF (字段数)更容易作为len(parts)检索。

在Python中移植awk字段

例如,让我们将单行代码从“ ”转换为Python。

awk中的原始文件是:

awk '!visited[$0]++' your_file > deduplicated_file

“真实的” Python转换将是:

import      
collections
import
sys
visited
=
collections .
defaultdict
(
int
)
for line
in
open
(
"your_file"
) :
    did_visit
= visited
[ line
]
    visited
[ line
] +
=
1
   
if
not did_visit:
       
sys .
stdout .
write
( line
)

但是,Python比awk具有更多的数据结构。 相反计数的访问(我们不使用,除非知道我们是否看到了一个线),为什么参观线路没有记录?

import      
sys
visited
=
set
(
)
for line
in
open
(
"your_file"
) :
   
if line
in visited:
       
continue
    visited.
add
( line
)
   
sys .
stdout .
write
( line
)

制作Pythonic AWK代码

Python社区提倡编写Pythonic代码,这意味着它遵循公认的代码风格。 更加Python化的方法将区分唯一性输入/输出的关注点。 此更改将使对代码进行单元测试更加容易:

def unique_generator      
( things
) :
    visited
=
set
(
)
   
for thing
in things:
       
if thing
in visited:
           
continue
        visited.
add
( thing
)
       
yield thing
import
sys
   
for line
in unique_generator
(
open
(
"your_file"
)
) :
   
sys .
stdout .
write
( line
)

将所有逻辑置于输入/输出代码之外,可以更好地分离问题,并提高代码的可用性和可测试性。

结论:Python可能是一个不错的选择

将awk脚本移植到Python时,通常是在考虑适当的Python语言代码样式时重新实现核心需求,而不是通过条件/操作对条件/操作进行笨拙的音译。 考虑原始上下文并产生高质量的Python解决方案。 虽然有时候使用awk的Bash单行代码可以完成这项工作,但Python编码是通往更易于维护的代码的途径。

另外,如果您正在编写awk脚本,我相信您也可以学习Python! 如果您有任何疑问,请告诉我。

翻译自:

python awk

转载地址:http://ppszd.baihongyu.com/

你可能感兴趣的文章
MySQL基础学习
查看>>
文件编码格式(转)
查看>>
Linux下安装rabbitmq
查看>>
曹德旺
查看>>
【转】判断点在多边形内(matlab)
查看>>
java基础之集合:List Set Map的概述以及使用场景
查看>>
Python 线程 进程 协程
查看>>
骨牌覆盖问题
查看>>
iOS语言中的KVO机制
查看>>
excel第一次打开报错 向程序发送命令时出错 多种解决办法含终极解决方法
查看>>
响应式web设计之CSS3 Media Queries
查看>>
实验三
查看>>
机器码和字节码
查看>>
—————————————1005————找规律的思想值得学习。
查看>>
要买多少路由器? 水题.
查看>>
python学习笔记第六节(函数,装饰器)
查看>>
System Operations on AWS - Lab 7 - CloudFormation
查看>>
[LeetCode#81]Search in Rotated Sorted Array II
查看>>
面试题13:在O(1)时间删除链表结点
查看>>
linux下PHP后台配置极光推送问题
查看>>